text: # Copyright 2014 Mirantis Inc.
  # All Rights Reserved.
  #
  #    Licensed under the Apache License, Version 2.0 (the "License"); you may
  #    not use this file except in compliance with the License. You may obtain
  #    a copy of the License at
  #
  #         http://www.apache.org/licenses/LICENSE-2.0
  #
  #    Unless required by applicable law or agreed to in writing, software
  #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  #    License for the specific language governing permissions and limitations
  #    under the License.
  
  """Test of Share Manager for Manila."""
  import datetime
  import hashlib
  import random
  from unittest import mock
  
  import ddt
  from oslo_concurrency import lockutils
  from oslo_serialization import jsonutils
  from oslo_utils import importutils
  from oslo_utils import timeutils
  import six
  
  from manila.common import constants
  from manila import context
  from manila import coordination
  from manila.data import rpcapi as data_rpc
  from manila import db
  from manila.db.sqlalchemy import models
  from manila import exception
  from manila.message import message_field
  from manila import quota
  from manila.share import api
  from manila.share import drivers_private_data
  from manila.share import manager
  from manila.share import migration as migration_api
  from manila.share import rpcapi
  from manila.share import share_types
  from manila import test
  from manila.tests.api import fakes as test_fakes
  from manila.tests import db_utils
  from manila.tests import fake_notifier
  from manila.tests import fake_share as fakes
  from manila.tests import fake_utils
  from manila.tests import utils as test_utils
  from manila import utils
  
  
  def fake_replica(**kwargs):
      return fakes.fake_replica(for_manager=True, **kwargs)
  
  
  class CustomTimeSleepException(Exception):
      pass
  
  
  class LockedOperationsTestCase(test.TestCase):
  
      class FakeManager(object):
  
          @manager.locked_share_replica_operation
          def fake_replica_operation(self, context, replica, share_id=None):
              pass
  
      def setUp(self):
          super(LockedOperationsTestCase, self).setUp()
          self.manager = self.FakeManager()
          self.fake_context = test_fakes.FakeRequestContext
          self.lock_call = self.mock_object(
              coordination, 'synchronized', mock.Mock(return_value=lambda f: f))
  
      @ddt.data({'id': 'FAKE_REPLICA_ID'}, 'FAKE_REPLICA_ID')
      @ddt.unpack
      def test_locked_share_replica_operation(self, **replica):
  
          self.manager.fake_replica_operation(self.fake_context, replica,
                                              share_id='FAKE_SHARE_ID')
  
          self.assertTrue(self.lock_call.called)
  
  
  @ddt.ddt
  class ShareManagerTestCase(test.TestCase):
  
      def setUp(self):
          super(ShareManagerTestCase, self).setUp()
          self.flags(share_driver='manila.tests.fake_driver.FakeShareDriver')
          # Define class directly, because this test suite dedicated
          # to specific manager.
          self.share_manager = importutils.import_object(
              "manila.share.manager.ShareManager")
          self.mock_object(self.share_manager.driver, 'do_setup')
          self.mock_object(self.share_manager.driver, 'check_for_setup_error')
          self.share_manager.driver._stats = {
              'share_group_stats': {'consistent_snapshot_support': None},
          }
          self.mock_object(self.share_manager.message_api, 'create')
          self.context = context.get_admin_context()
          self.share_manager.driver.initialized = True
          mock.patch.object(
              lockutils, 'lock', fake_utils.get_fake_lock_context())
          self.synchronized_lock_decorator_call = self.mock_object(
              coordination, 'synchronized', mock.Mock(return_value=lambda f: f))
  
      def test_share_manager_instance(self):
          fake_service_name = "fake_service"
          importutils_mock = mock.Mock()
          self.mock_object(importutils, "import_object", importutils_mock)
          private_data_mock = mock.Mock()
          self.mock_object(drivers_private_data, "DriverPrivateData",
                           private_data_mock)
          self.mock_object(manager.ShareManager, '_init_hook_drivers')
  
          share_manager = manager.ShareManager(service_name=fake_service_name)
  
          private_data_mock.assert_called_once_with(
              context=mock.ANY,
              backend_host=share_manager.host,
              config_group=fake_service_name
          )
          self.assertTrue(importutils_mock.called)
          self.assertTrue(manager.ShareManager._init_hook_drivers.called)
  
      def test__init_hook_drivers(self):
          fake_service_name = "fake_service"
          importutils_mock = mock.Mock()
          self.mock_object(importutils, "import_object", importutils_mock)
          self.mock_object(drivers_private_data, "DriverPrivateData")
          share_manager = manager.ShareManager(service_name=fake_service_name)
          share_manager.configuration.safe_get = mock.Mock(
              return_value=["Foo", "Bar"])
          self.assertEqual(0, len(share_manager.hooks))
          importutils_mock.reset()
  
          share_manager._init_hook_drivers()
  
          self.assertEqual(
              len(share_manager.configuration.safe_get.return_value),
              len(share_manager.hooks))
          importutils_mock.assert_has_calls([
              mock.call(
                  hook,
                  configuration=share_manager.configuration,
                  host=share_manager.host
              ) for hook in share_manager.configuration.safe_get.return_value
          ], any_order=True)
  
      def test__execute_periodic_hook(self):
          share_instances_mock = mock.Mock()
          hook_data_mock = mock.Mock()
          self.mock_object(
              self.share_manager.db,
              "share_instances_get_all_by_host",
              share_instances_mock)
          self.mock_object(
              self.share_manager.driver,
              "get_periodic_hook_data",
              hook_data_mock)
          self.share_manager.hooks = [mock.Mock(return_value=i) for i in (0, 1)]
  
          self.share_manager._execute_periodic_hook(self.context)
  
          share_instances_mock.assert_called_once_with(
              context=self.context, host=self.share_manager.host)
          hook_data_mock.assert_called_once_with(
              context=self.context,
              share_instances=share_instances_mock.return_value)
          for mock_hook in self.share_manager.hooks:
              mock_hook.execute_periodic_hook.assert_called_once_with(
                  context=self.context,
                  periodic_hook_data=hook_data_mock.return_value)
  
      def test_is_service_ready(self):
          self.assertTrue(self.share_manager.is_service_ready())
  
          # switch it to false and check again
          self.share_manager.driver.initialized = False
          self.assertFalse(self.share_manager.is_service_ready())
  
      def test_init_host_with_no_shares(self):
          self.mock_object(self.share_manager.db,
                           'share_instances_get_all_by_host',
                           mock.Mock(return_value=[]))
  
          self.share_manager.init_host(reexport=True)
  
          self.assertTrue(self.share_manager.driver.initialized)
          (self.share_manager.db.share_instances_get_all_by_host.
              assert_called_once_with(utils.IsAMatcher(context.RequestContext),
                                      self.share_manager.host))
          self.share_manager.driver.do_setup.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext))
          (self.share_manager.driver.check_for_setup_error.
              assert_called_once_with())
  
      @ddt.data(
          "connection_get_info",
          "migration_cancel",
          "migration_get_progress",
          "migration_complete",
          "migration_start",
          "create_share_instance",
          "manage_share",
          "unmanage_share",
          "delete_share_instance",
          "delete_free_share_servers",
          "create_snapshot",
          "delete_snapshot",
          "update_access",
          "_report_driver_status",
          "_execute_periodic_hook",
          "publish_service_capabilities",
          "delete_share_server",
          "extend_share",
          "shrink_share",
          "create_share_group",
          "delete_share_group",
          "create_share_group_snapshot",
          "delete_share_group_snapshot",
          "create_share_replica",
          "delete_share_replica",
          "promote_share_replica",
          "periodic_share_replica_update",
          "update_share_replica",
          "create_replicated_snapshot",
          "delete_replicated_snapshot",
          "periodic_share_replica_snapshot_update",
      )
      def test_call_driver_when_its_init_failed(self, method_name):
          self.mock_object(self.share_manager.driver, 'do_setup',
                           mock.Mock(side_effect=Exception()))
          # break the endless retry loop
          with mock.patch("time.sleep",
                          side_effect=CustomTimeSleepException()):
              self.assertRaises(CustomTimeSleepException,
                                self.share_manager.init_host)
          self.assertRaises(
              exception.DriverNotInitialized,
              getattr(self.share_manager, method_name),
              'foo', 'bar', 'quuz'
          )
  
      @ddt.data("do_setup", "check_for_setup_error")
      def test_init_host_with_driver_failure(self, method_name):
          self.mock_object(self.share_manager.driver, method_name,
                           mock.Mock(side_effect=Exception()))
          self.mock_object(manager.LOG, 'exception')
          self.share_manager.driver.initialized = False
  
          with mock.patch("time.sleep",
                          side_effect=CustomTimeSleepException()):
              self.assertRaises(CustomTimeSleepException,
                                self.share_manager.init_host)
  
          manager.LOG.exception.assert_called_once_with(
              mock.ANY, "%(name)s@%(host)s" %
              {'name': self.share_manager.driver.__class__.__name__,
               'host': self.share_manager.host})
          self.assertFalse(self.share_manager.driver.initialized)
  
      def _setup_init_mocks(self, setup_access_rules=True):
          instances = [
              db_utils.create_share(id='fake_id_1',
                                    status=constants.STATUS_AVAILABLE,
                                    display_name='fake_name_1').instance,
              db_utils.create_share(id='fake_id_2',
                                    status=constants.STATUS_ERROR,
                                    display_name='fake_name_2').instance,
              db_utils.create_share(id='fake_id_3',
                                    status=constants.STATUS_AVAILABLE,
                                    display_name='fake_name_3').instance,
              db_utils.create_share(
                  id='fake_id_4',
                  status=constants.STATUS_MIGRATING,
                  task_state=constants.TASK_STATE_MIGRATION_IN_PROGRESS,
                  display_name='fake_name_4').instance,
              db_utils.create_share(id='fake_id_5',
                                    status=constants.STATUS_AVAILABLE,
                                    display_name='fake_name_5').instance,
              db_utils.create_share(
                  id='fake_id_6',
                  status=constants.STATUS_MIGRATING,
                  task_state=constants.TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS,
                  display_name='fake_name_6').instance,
              db_utils.create_share(
                  id='fake_id_7', status=constants.STATUS_CREATING_FROM_SNAPSHOT,
                  display_name='fake_name_7').instance,
          ]
  
          instances[4]['access_rules_status'] = (
              constants.SHARE_INSTANCE_RULES_SYNCING)
  
          if not setup_access_rules:
              return instances
  
          rules = [
              db_utils.create_access(share_id='fake_id_1'),
              db_utils.create_access(share_id='fake_id_3'),
          ]
  
          return instances, rules
  
      @ddt.data(("some_hash", {"db_version": "test_version"}),
                ("ddd86ec90923b686597501e2f2431f3af59238c0",
                 {"db_version": "test_version"}),
                (None, {"db_version": "test_version"}),
                (None, None))
      @ddt.unpack
      def test_init_host_with_shares_and_rules(
              self, old_backend_info_hash, new_backend_info):
  
          # initialization of test data
          def raise_share_access_exists(*args, **kwargs):
              raise exception.ShareAccessExists(
                  access_type='fake_access_type', access='fake_access')
  
          new_backend_info_hash = (hashlib.sha1(six.text_type(
              sorted(new_backend_info.items())).encode('utf-8')).hexdigest() if
              new_backend_info else None)
          old_backend_info = {'info_hash': old_backend_info_hash}
          share_server = fakes.fake_share_server_get()
          instances, rules = self._setup_init_mocks()
          fake_export_locations = ['fake/path/1', 'fake/path']
          fake_update_instances = {
              instances[0]['id']: {'export_locations': fake_export_locations},
              instances[2]['id']: {'export_locations': fake_export_locations}
          }
          instances[0]['access_rules_status'] = ''
          instances[2]['access_rules_status'] = ''
          self.mock_object(self.share_manager.db,
                           'backend_info_get',
                           mock.Mock(return_value=old_backend_info))
          mock_backend_info_update = self.mock_object(
              self.share_manager.db, 'backend_info_update')
          self.mock_object(self.share_manager.driver, 'get_backend_info',
                           mock.Mock(return_value=new_backend_info))
          mock_share_get_all_by_host = self.mock_object(
              self.share_manager.db, 'share_instances_get_all_by_host',
              mock.Mock(return_value=instances))
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(side_effect=[instances[0], instances[2],
                                                  instances[4]]))
          self.mock_object(self.share_manager.db,
                           'share_export_locations_update')
          mock_ensure_shares = self.mock_object(
              self.share_manager.driver, 'ensure_shares',
              mock.Mock(return_value=fake_update_instances))
          self.mock_object(self.share_manager, '_ensure_share_instance_has_pool')
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=share_server))
          self.mock_object(self.share_manager, '_get_share_server_dict',
                           mock.Mock(return_value=share_server))
          self.mock_object(self.share_manager, 'publish_service_capabilities',
                           mock.Mock())
          self.mock_object(self.share_manager.db,
                           'share_access_get_all_for_share',
                           mock.Mock(return_value=rules))
          self.mock_object(
              self.share_manager.access_helper,
              'update_access_rules',
              mock.Mock(side_effect=raise_share_access_exists)
          )
  
          dict_instances = [self._get_share_instance_dict(
              instance, share_server=share_server) for instance in instances]
  
          # call of 'init_host' method
          self.share_manager.init_host(reexport=True)
  
          # verification of call
          exports_update = self.share_manager.db.share_export_locations_update
          self.share_manager.driver.do_setup.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext))
          (self.share_manager.driver.check_for_setup_error.
              assert_called_once_with())
  
          if new_backend_info_hash == old_backend_info_hash:
              mock_backend_info_update.assert_not_called()
              mock_ensure_shares.assert_not_called()
              mock_share_get_all_by_host.assert_not_called()
          else:
              mock_backend_info_update.assert_called_once_with(
                  utils.IsAMatcher(context.RequestContext),
                  self.share_manager.host, new_backend_info_hash)
              self.share_manager.driver.ensure_shares.assert_called_once_with(
                  utils.IsAMatcher(context.RequestContext),
                  [dict_instances[0], dict_instances[2], dict_instances[4]])
              mock_share_get_all_by_host.assert_called_once_with(
                  utils.IsAMatcher(context.RequestContext),
                  self.share_manager.host)
              exports_update.assert_has_calls([
                  mock.call(mock.ANY, instances[0]['id'], fake_export_locations,
                            reexport=True),
                  mock.call(mock.ANY, instances[2]['id'], fake_export_locations,
                            reexport=True)
              ])
              (self.share_manager._ensure_share_instance_has_pool.
                  assert_has_calls([
                      mock.call(utils.IsAMatcher(context.RequestContext),
                                instances[0]),
                      mock.call(utils.IsAMatcher(context.RequestContext),
                                instances[2]),
                  ]))
              self.share_manager._get_share_server.assert_has_calls([
                  mock.call(utils.IsAMatcher(context.RequestContext),
                            instances[0]),
                  mock.call(utils.IsAMatcher(context.RequestContext),
                            instances[2]),
              ])
              # (self.share_manager.publish_service_capabilities.
              #     assert_called_once_with(
              #         utils.IsAMatcher(context.RequestContext)))
              (self.share_manager.access_helper.update_access_rules.
               assert_has_calls([
                   mock.call(mock.ANY, instances[0]['id'],
                             share_server=share_server),
                   mock.call(mock.ANY, instances[2]['id'],
                             share_server=share_server),
               ]))
  
      @ddt.data(("some_hash", {"db_version": "test_version"}),
                ("ddd86ec90923b686597501e2f2431f3af59238c0",
                 {"db_version": "test_version"}),
                (None, {"db_version": "test_version"}),
                (None, None))
      @ddt.unpack
      def test_init_host_without_shares_and_rules(
              self, old_backend_info_hash, new_backend_info):
  
          old_backend_info = {'info_hash': old_backend_info_hash}
          new_backend_info_hash = (hashlib.sha1(six.text_type(
              sorted(new_backend_info.items())).encode('utf-8')).hexdigest() if
              new_backend_info else None)
          mock_backend_info_update = self.mock_object(
              self.share_manager.db, 'backend_info_update')
          self.mock_object(
              self.share_manager.db, 'backend_info_get',
              mock.Mock(return_value=old_backend_info))
          self.mock_object(self.share_manager.driver, 'get_backend_info',
                           mock.Mock(return_value=new_backend_info))
          self.mock_object(self.share_manager, 'publish_service_capabilities',
                           mock.Mock())
          mock_ensure_shares = self.mock_object(
              self.share_manager.driver, 'ensure_shares')
          mock_share_instances_get_all_by_host = self.mock_object(
              self.share_manager.db, 'share_instances_get_all_by_host',
              mock.Mock(return_value=[]))
  
          # call of 'init_host' method
          self.share_manager.init_host(reexport=True)
          if new_backend_info_hash == old_backend_info_hash:
              mock_backend_info_update.assert_not_called()
              mock_ensure_shares.assert_not_called()
              mock_share_instances_get_all_by_host.assert_not_called()
          else:
              mock_backend_info_update.assert_called_once_with(
                  utils.IsAMatcher(context.RequestContext),
                  self.share_manager.host, new_backend_info_hash)
              self.share_manager.driver.do_setup.assert_called_once_with(
                  utils.IsAMatcher(context.RequestContext))
              self.share_manager.db.backend_info_get.assert_called_once_with(
                  utils.IsAMatcher(context.RequestContext),
                  self.share_manager.host)
              self.share_manager.driver.get_backend_info.assert_called_once_with(
                  utils.IsAMatcher(context.RequestContext))
              mock_ensure_shares.assert_not_called()
              mock_share_instances_get_all_by_host.assert_called_once_with(
                  utils.IsAMatcher(context.RequestContext),
                  self.share_manager.host)
  
      @ddt.data(exception.ManilaException, ['fake/path/1', 'fake/path'])
      def test_init_host_with_ensure_share(self, expected_ensure_share_result):
          def raise_NotImplementedError(*args, **kwargs):
              raise NotImplementedError
  
          instances = self._setup_init_mocks(setup_access_rules=False)
          share_server = fakes.fake_share_server_get()
          self.mock_object(self.share_manager.db,
                           'share_instances_get_all_by_host',
                           mock.Mock(return_value=instances))
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(side_effect=[instances[0], instances[2],
                                                  instances[3]]))
          self.mock_object(
              self.share_manager.driver, 'ensure_shares',
              mock.Mock(side_effect=raise_NotImplementedError))
          self.mock_object(self.share_manager.driver, 'ensure_share',
                           mock.Mock(side_effect=expected_ensure_share_result))
          self.mock_object(
              self.share_manager, '_ensure_share_instance_has_pool')
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=share_server))
          self.mock_object(self.share_manager, '_get_share_server_dict',
                           mock.Mock(return_value=share_server))
          self.mock_object(self.share_manager, 'publish_service_capabilities')
          self.mock_object(manager.LOG, 'error')
          self.mock_object(manager.LOG, 'info')
  
          dict_instances = [self._get_share_instance_dict(
              instance, share_server=share_server) for instance in instances]
  
          # call of 'init_host' method
          self.share_manager.init_host(reexport=True)
  
          # verification of call
          (self.share_manager.db.share_instances_get_all_by_host.
              assert_called_once_with(utils.IsAMatcher(context.RequestContext),
                                      self.share_manager.host))
          self.share_manager.driver.do_setup.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext))
          self.share_manager.driver.check_for_setup_error.assert_called_with()
          self.share_manager._ensure_share_instance_has_pool.assert_has_calls([
              mock.call(utils.IsAMatcher(context.RequestContext), instances[0]),
              mock.call(utils.IsAMatcher(context.RequestContext), instances[2]),
          ])
          self.share_manager.driver.ensure_shares.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              [dict_instances[0], dict_instances[2], dict_instances[3]])
          self.share_manager._get_share_server.assert_has_calls([
              mock.call(utils.IsAMatcher(context.RequestContext), instances[0]),
              mock.call(utils.IsAMatcher(context.RequestContext), instances[2]),
          ])
          self.share_manager.driver.ensure_share.assert_has_calls([
              mock.call(utils.IsAMatcher(context.RequestContext),
                        dict_instances[0],
                        share_server=share_server),
              mock.call(utils.IsAMatcher(context.RequestContext),
                        dict_instances[2],
                        share_server=share_server),
          ])
          # (self.share_manager.publish_service_capabilities.
          #     assert_called_once_with(
          #         utils.IsAMatcher(context.RequestContext)))
          manager.LOG.info.assert_any_call(
              mock.ANY,
              {'task': constants.TASK_STATE_MIGRATION_IN_PROGRESS,
               'id': instances[3]['id']},
          )
          manager.LOG.info.assert_any_call(
              mock.ANY,
              {'id': instances[1]['id'], 'status': instances[1]['status']},
          )
  
      def _get_share_instance_dict(self, share_instance, **kwargs):
          # TODO(gouthamr): remove method when the db layer returns primitives
          share_instance_ref = {
              'id': share_instance.get('id'),
              'name': share_instance.get('name'),
              'share_id': share_instance.get('share_id'),
              'host': share_instance.get('host'),
              'status': share_instance.get('status'),
              'replica_state': share_instance.get('replica_state'),
              'availability_zone_id': share_instance.get('availability_zone_id'),
              'share_network_id': share_instance.get('share_network_id'),
              'share_server_id': share_instance.get('share_server_id'),
              'deleted': share_instance.get('deleted'),
              'terminated_at': share_instance.get('terminated_at'),
              'launched_at': share_instance.get('launched_at'),
              'scheduled_at': share_instance.get('scheduled_at'),
              'updated_at': share_instance.get('updated_at'),
              'deleted_at': share_instance.get('deleted_at'),
              'created_at': share_instance.get('created_at'),
              'share_server': kwargs.get('share_server'),
              'access_rules_status': share_instance.get('access_rules_status'),
              # Share details
              'user_id': share_instance.get('user_id'),
              'project_id': share_instance.get('project_id'),
              'size': share_instance.get('size'),
              'display_name': share_instance.get('display_name'),
              'display_description': share_instance.get('display_description'),
              'snapshot_id': share_instance.get('snapshot_id'),
              'share_proto': share_instance.get('share_proto'),
              'share_type_id': share_instance.get('share_type_id'),
              'is_public': share_instance.get('is_public'),
              'share_group_id': share_instance.get('share_group_id'),
              'source_share_group_snapshot_member_id': share_instance.get(
                  'source_share_group_snapshot_member_id'),
              'availability_zone': share_instance.get('availability_zone'),
              'export_locations': share_instance.get('export_locations') or [],
          }
          return share_instance_ref
  
      def test_init_host_with_exception_on_ensure_shares(self):
          def raise_exception(*args, **kwargs):
              raise exception.ManilaException(message="Fake raise")
  
          instances = self._setup_init_mocks(setup_access_rules=False)
          mock_ensure_share = self.mock_object(
              self.share_manager.driver, 'ensure_share')
          self.mock_object(self.share_manager.db,
                           'share_instances_get_all_by_host',
                           mock.Mock(return_value=instances))
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(side_effect=[instances[0], instances[2],
                                                  instances[3]]))
          self.mock_object(
              self.share_manager.driver, 'ensure_shares',
              mock.Mock(side_effect=raise_exception))
          self.mock_object(
              self.share_manager, '_ensure_share_instance_has_pool')
          self.mock_object(db, 'share_server_get',
                           mock.Mock(return_value=fakes.fake_share_server_get()))
  
          dict_instances = [self._get_share_instance_dict(instance)
                            for instance in instances]
  
          # call of 'init_host' method
          self.share_manager.init_host(reexport=True)
  
          # verification of call
          (self.share_manager.db.share_instances_get_all_by_host.
           assert_called_once_with(utils.IsAMatcher(context.RequestContext),
                                   self.share_manager.host))
          self.share_manager.driver.do_setup.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext))
          self.share_manager.driver.check_for_setup_error.assert_called_with()
          self.share_manager._ensure_share_instance_has_pool.assert_has_calls([
              mock.call(utils.IsAMatcher(context.RequestContext), instances[0]),
              mock.call(utils.IsAMatcher(context.RequestContext), instances[2]),
          ])
          self.share_manager.driver.ensure_shares.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              [dict_instances[0], dict_instances[2], dict_instances[3]])
          mock_ensure_share.assert_not_called()
  
      def test_init_host_with_exception_on_get_backend_info(self):
          def raise_exception(*args, **kwargs):
              raise exception.ManilaException(message="Fake raise")
  
          old_backend_info = {'info_hash': "test_backend_info"}
          mock_ensure_share = self.mock_object(
              self.share_manager.driver, 'ensure_share')
          mock_ensure_shares = self.mock_object(
              self.share_manager.driver, 'ensure_shares')
          self.mock_object(self.share_manager.db,
                           'backend_info_get',
                           mock.Mock(return_value=old_backend_info))
          self.mock_object(
              self.share_manager.driver, 'get_backend_info',
              mock.Mock(side_effect=raise_exception))
          # call of 'init_host' method
          self.assertRaises(
              exception.ManilaException,
              self.share_manager.init_host,
              reexport=True
          )
  
          # verification of call
          self.share_manager.db.backend_info_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), self.share_manager.host)
          self.share_manager.driver.get_backend_info.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext))
          mock_ensure_share.assert_not_called()
          mock_ensure_shares.assert_not_called()
  
      def test_init_host_with_exception_on_update_access_rules(self):
          def raise_exception(*args, **kwargs):
              raise exception.ManilaException(message="Fake raise")
  
          instances, rules = self._setup_init_mocks()
          share_server = fakes.fake_share_server_get()
          fake_update_instances = {
              instances[0]['id']: {'status': 'available'},
              instances[2]['id']: {'status': 'available'},
              instances[4]['id']: {'status': 'available'}
          }
          smanager = self.share_manager
          self.mock_object(smanager.db, 'share_instances_get_all_by_host',
                           mock.Mock(return_value=instances))
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(side_effect=[instances[0], instances[2],
                                                  instances[4]]))
          self.mock_object(self.share_manager.driver, 'ensure_share',
                           mock.Mock(return_value=None))
          self.mock_object(self.share_manager.driver, 'ensure_shares',
                           mock.Mock(return_value=fake_update_instances))
          self.mock_object(smanager, '_ensure_share_instance_has_pool')
          self.mock_object(smanager, '_get_share_server',
                           mock.Mock(return_value=share_server))
          self.mock_object(smanager, 'publish_service_capabilities')
          self.mock_object(manager.LOG, 'exception')
          self.mock_object(manager.LOG, 'info')
          self.mock_object(smanager.db, 'share_access_get_all_for_share',
                           mock.Mock(return_value=rules))
          self.mock_object(smanager.access_helper, 'update_access_rules',
                           mock.Mock(side_effect=raise_exception))
          self.mock_object(smanager, '_get_share_server_dict',
                           mock.Mock(return_value=share_server))
  
          dict_instances = [self._get_share_instance_dict(
              instance, share_server=share_server) for instance in instances]
  
          # call of 'init_host' method
          smanager.init_host(reexport=True)
  
          # verification of call
          (smanager.db.share_instances_get_all_by_host.
              assert_called_once_with(utils.IsAMatcher(context.RequestContext),
                                      smanager.host))
          smanager.driver.do_setup.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext))
          smanager.driver.check_for_setup_error.assert_called_with()
          smanager._ensure_share_instance_has_pool.assert_has_calls([
              mock.call(utils.IsAMatcher(context.RequestContext), instances[0]),
              mock.call(utils.IsAMatcher(context.RequestContext), instances[2]),
          ])
          smanager.driver.ensure_shares.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              [dict_instances[0], dict_instances[2], dict_instances[4]])
          # (self.share_manager.publish_service_capabilities.
          #     assert_called_once_with(
          #         utils.IsAMatcher(context.RequestContext)))
          manager.LOG.info.assert_any_call(
              mock.ANY,
              {'task': constants.TASK_STATE_MIGRATION_IN_PROGRESS,
               'id': instances[3]['id']},
          )
          manager.LOG.info.assert_any_call(
              mock.ANY,
              {'id': instances[1]['id'], 'status': instances[1]['status']},
          )
          smanager.access_helper.update_access_rules.assert_has_calls([
              mock.call(utils.IsAMatcher(context.RequestContext),
                        instances[4]['id'], share_server=share_server),
          ])
          manager.LOG.exception.assert_has_calls([
              mock.call(mock.ANY, mock.ANY),
          ])
  
      def test_create_share_instance_from_snapshot_with_server(self):
          """Test share can be created from snapshot if server exists."""
          network = db_utils.create_share_network()
          subnet = db_utils.create_share_network_subnet(
              share_network_id=network['id'])
          server = db_utils.create_share_server(
              share_network_subnet_id=subnet['id'], host='fake_host',
              backend_details=dict(fake='fake'))
          parent_share = db_utils.create_share(share_network_id='net-id',
                                               share_server_id=server['id'])
          share = db_utils.create_share()
          share_id = share['id']
          snapshot = db_utils.create_snapshot(share_id=parent_share['id'])
          snapshot_id = snapshot['id']
  
          self.share_manager.create_share_instance(
              self.context, share.instance['id'], snapshot_id=snapshot_id)
          self.assertEqual(share_id, db.share_get(context.get_admin_context(),
                           share_id).id)
  
          shr = db.share_get(self.context, share_id)
          self.assertEqual(constants.STATUS_AVAILABLE, shr['status'])
          self.assertEqual(server['id'], shr['instance']['share_server_id'])
  
      def test_create_share_instance_from_snapshot_with_server_not_found(self):
          """Test creation from snapshot fails if server not found."""
          parent_share = db_utils.create_share(share_network_id='net-id',
                                               share_server_id='fake-id')
          share = db_utils.create_share()
          share_id = share['id']
          snapshot = db_utils.create_snapshot(share_id=parent_share['id'])
          snapshot_id = snapshot['id']
  
          self.assertRaises(exception.ShareServerNotFound,
                            self.share_manager.create_share_instance,
                            self.context,
                            share.instance['id'],
                            snapshot_id=snapshot_id
                            )
  
          shr = db.share_get(self.context, share_id)
          self.assertEqual(constants.STATUS_ERROR, shr['status'])
  
      def test_create_share_instance_from_snapshot_status_creating(self):
          """Test share can be created from snapshot in asynchronous mode."""
          share = db_utils.create_share()
          share_id = share['id']
          snapshot = db_utils.create_snapshot(share_id=share_id)
          snapshot_id = snapshot['id']
          create_from_snap_ret = {
              'status': constants.STATUS_CREATING_FROM_SNAPSHOT,
          }
          driver_call = self.mock_object(
              self.share_manager.driver, 'create_share_from_snapshot',
              mock.Mock(return_value=create_from_snap_ret))
          self.share_manager.create_share_instance(
              self.context, share.instance['id'], snapshot_id=snapshot_id)
          self.assertTrue(driver_call.called)
          self.assertEqual(share_id, db.share_get(context.get_admin_context(),
                           share_id).id)
  
          shr = db.share_get(self.context, share_id)
          self.assertTrue(driver_call.called)
          self.assertEqual(constants.STATUS_CREATING_FROM_SNAPSHOT,
                           shr['status'])
          self.assertEqual(0, len(shr['export_locations']))
  
      def test_create_share_instance_from_snapshot_invalid_status(self):
          """Test share can't be created from snapshot with 'creating' status."""
          share = db_utils.create_share()
          share_id = share['id']
          snapshot = db_utils.create_snapshot(share_id=share_id)
          snapshot_id = snapshot['id']
          create_from_snap_ret = {
              'status': constants.STATUS_CREATING,
          }
          driver_call = self.mock_object(
              self.share_manager.driver, 'create_share_from_snapshot',
              mock.Mock(return_value=create_from_snap_ret))
  
          self.assertRaises(exception.InvalidShareInstance,
                            self.share_manager.create_share_instance,
                            self.context,
                            share.instance['id'],
                            snapshot_id=snapshot_id)
          self.assertTrue(driver_call.called)
          shr = db.share_get(self.context, share_id)
          self.assertEqual(constants.STATUS_ERROR, shr['status'])
  
      def test_create_share_instance_from_snapshot_export_locations_only(self):
          """Test share can be created from snapshot on old driver interface."""
          share = db_utils.create_share()
          share_id = share['id']
          snapshot = db_utils.create_snapshot(share_id=share_id)
          snapshot_id = snapshot['id']
          create_from_snap_ret = ['/path/fake', '/path/fake2', '/path/fake3']
  
          driver_call = self.mock_object(
              self.share_manager.driver, 'create_share_from_snapshot',
              mock.Mock(return_value=create_from_snap_ret))
          self.share_manager.create_share_instance(
              self.context, share.instance['id'], snapshot_id=snapshot_id)
          self.assertTrue(driver_call.called)
          self.assertEqual(share_id, db.share_get(context.get_admin_context(),
                           share_id).id)
  
          shr = db.share_get(self.context, share_id)
          self.assertEqual(constants.STATUS_AVAILABLE, shr['status'])
          self.assertEqual(3, len(shr['export_locations']))
  
      def test_create_share_instance_from_snapshot(self):
          """Test share can be created from snapshot."""
          share = db_utils.create_share()
          share_id = share['id']
          snapshot = db_utils.create_snapshot(share_id=share_id)
          snapshot_id = snapshot['id']
  
          self.share_manager.create_share_instance(
              self.context, share.instance['id'], snapshot_id=snapshot_id)
          self.assertEqual(share_id, db.share_get(context.get_admin_context(),
                           share_id).id)
  
          shr = db.share_get(self.context, share_id)
          self.assertEqual(constants.STATUS_AVAILABLE, shr['status'])
          self.assertGreater(len(shr['export_location']), 0)
          self.assertEqual(2, len(shr['export_locations']))
  
      def test_create_share_instance_for_share_with_replication_support(self):
          """Test update call is made to update replica_state."""
          share = db_utils.create_share(replication_type='writable')
          share_id = share['id']
  
          self.share_manager.create_share_instance(self.context,
                                                   share.instance['id'])
  
          self.assertEqual(share_id, db.share_get(context.get_admin_context(),
                           share_id).id)
  
          shr = db.share_get(self.context, share_id)
          shr_instance = db.share_instance_get(self.context,
                                               share.instance['id'])
  
          self.assertEqual(constants.STATUS_AVAILABLE, shr['status'],)
          self.assertEqual(constants.REPLICA_STATE_ACTIVE,
                           shr_instance['replica_state'])
  
      @ddt.data([], None)
      def test_create_share_replica_no_active_replicas(self, active_replicas):
          replica = fake_replica()
          self.mock_object(db, 'share_replicas_get_available_active_replica',
                           mock.Mock(return_value=active_replicas))
          self.mock_object(
              db, 'share_replica_get', mock.Mock(return_value=replica))
          mock_replica_update_call = self.mock_object(db, 'share_replica_update')
          mock_driver_replica_call = self.mock_object(
              self.share_manager.driver, 'create_replica')
  
          self.assertRaises(exception.ReplicationException,
                            self.share_manager.create_share_replica,
                            self.context, replica)
          mock_replica_update_call.assert_called_once_with(
              mock.ANY, replica['id'], {'status': constants.STATUS_ERROR,
                                        'replica_state': constants.STATUS_ERROR})
          self.assertFalse(mock_driver_replica_call.called)
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.CREATE,
              replica['project_id'],
              resource_type=message_field.Resource.SHARE_REPLICA,
              resource_id=replica['id'],
              detail=message_field.Detail.NO_ACTIVE_REPLICA)
  
      def test_create_share_replica_with_share_network_id_and_not_dhss(self):
          replica = fake_replica()
          manager.CONF.set_default('driver_handles_share_servers', False)
          self.mock_object(db, 'share_access_get_all_for_share',
                           mock.Mock(return_value=[]))
          self.mock_object(db, 'share_replicas_get_available_active_replica',
                           mock.Mock(return_value=fake_replica(id='fake2')))
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          mock_replica_update_call = self.mock_object(db, 'share_replica_update')
          mock_driver_replica_call = self.mock_object(
              self.share_manager.driver, 'create_replica')
  
          self.assertRaises(exception.InvalidDriverMode,
                            self.share_manager.create_share_replica,
                            self.context, replica)
          mock_replica_update_call.assert_called_once_with(
              mock.ANY, replica['id'], {'status': constants.STATUS_ERROR,
                                        'replica_state': constants.STATUS_ERROR})
          self.assertFalse(mock_driver_replica_call.called)
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.CREATE,
              replica['project_id'],
              resource_type=message_field.Resource.SHARE_REPLICA,
              resource_id=replica['id'],
              detail=message_field.Detail.UNEXPECTED_NETWORK)
  
      def test_create_share_replica_with_share_server_exception(self):
          replica = fake_replica()
          share_network_subnet = db_utils.create_share_network_subnet(
              share_network_id=replica['share_network_id'],
              availability_zone_id=replica['availability_zone_id'])
          manager.CONF.set_default('driver_handles_share_servers', True)
          self.mock_object(db, 'share_instance_access_copy',
                           mock.Mock(return_value=[]))
          self.mock_object(db, 'share_replicas_get_available_active_replica',
                           mock.Mock(return_value=fake_replica(id='fake2')))
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(db,
                           'share_network_subnet_get_by_availability_zone_id',
                           mock.Mock(return_value=share_network_subnet))
          mock_replica_update_call = self.mock_object(db, 'share_replica_update')
          mock_driver_replica_call = self.mock_object(
              self.share_manager.driver, 'create_replica')
  
          self.assertRaises(exception.NotFound,
                            self.share_manager.create_share_replica,
                            self.context, replica)
          mock_replica_update_call.assert_called_once_with(
              mock.ANY, replica['id'], {'status': constants.STATUS_ERROR,
                                        'replica_state': constants.STATUS_ERROR})
          self.assertFalse(mock_driver_replica_call.called)
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.CREATE,
              replica['project_id'],
              resource_type=message_field.Resource.SHARE_REPLICA,
              resource_id=replica['id'],
              detail=message_field.Detail.NO_SHARE_SERVER)
  
      def test_create_share_replica_driver_error_on_creation(self):
          fake_access_rules = [{'id': '1'}, {'id': '2'}, {'id': '3'}]
          replica = fake_replica()
          replica_2 = fake_replica(id='fake2')
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(db, 'share_instance_access_copy',
                           mock.Mock(return_value=fake_access_rules))
          self.mock_object(db, 'share_replicas_get_available_active_replica',
                           mock.Mock(return_value=replica_2))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica, replica_2]))
          self.mock_object(self.share_manager,
                           '_provide_share_server_for_share',
                           mock.Mock(return_value=('FAKE_SERVER', replica)))
          self.mock_object(self.share_manager,
                           '_get_replica_snapshots_for_snapshot',
                           mock.Mock(return_value=[]))
          mock_replica_update_call = self.mock_object(db, 'share_replica_update')
          mock_export_locs_update_call = self.mock_object(
              db, 'share_export_locations_update')
          mock_log_warning = self.mock_object(manager.LOG, 'warning')
          mock_log_info = self.mock_object(manager.LOG, 'info')
          self.mock_object(db, 'share_instance_access_get',
                           mock.Mock(return_value=fake_access_rules[0]))
          mock_share_replica_access_update = self.mock_object(
              self.share_manager.access_helper,
              'get_and_update_share_instance_access_rules_status')
          self.mock_object(self.share_manager, '_get_share_server')
  
          driver_call = self.mock_object(
              self.share_manager.driver, 'create_replica',
              mock.Mock(side_effect=exception.ManilaException))
  
          self.assertRaises(exception.ManilaException,
                            self.share_manager.create_share_replica,
                            self.context, replica)
          mock_replica_update_call.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), replica['id'],
              {'status': constants.STATUS_ERROR,
               'replica_state': constants.STATUS_ERROR})
          mock_share_replica_access_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              share_instance_id=replica['id'],
              status=constants.SHARE_INSTANCE_RULES_ERROR)
          self.assertFalse(mock_export_locs_update_call.called)
          self.assertTrue(mock_log_warning.called)
          self.assertFalse(mock_log_info.called)
          self.assertTrue(driver_call.called)
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.CREATE,
              replica['project_id'],
              resource_type=message_field.Resource.SHARE_REPLICA,
              resource_id=replica['id'],
              exception=mock.ANY)
  
      def test_create_share_replica_invalid_locations_state(self):
          driver_retval = {
              'export_locations': 'FAKE_EXPORT_LOC',
          }
          replica = fake_replica(share_network='',
                                 access_rules_status=constants.STATUS_ACTIVE)
          replica_2 = fake_replica(id='fake2')
          fake_access_rules = [{'id': '1'}, {'id': '2'}]
          self.mock_object(db, 'share_replicas_get_available_active_replica',
                           mock.Mock(return_value=replica_2))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica, replica_2]))
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(db, 'share_instance_access_copy',
                           mock.Mock(return_value=fake_access_rules))
          self.mock_object(self.share_manager,
                           '_provide_share_server_for_share',
                           mock.Mock(return_value=('FAKE_SERVER', replica)))
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=None))
          self.mock_object(self.share_manager,
                           '_get_replica_snapshots_for_snapshot',
                           mock.Mock(return_value=[]))
          mock_replica_update_call = self.mock_object(db, 'share_replica_update')
          mock_export_locs_update_call = self.mock_object(
              db, 'share_export_locations_update')
          mock_log_info = self.mock_object(manager.LOG, 'info')
          mock_log_warning = self.mock_object(manager.LOG, 'warning')
          mock_log_error = self.mock_object(manager.LOG, 'error')
          driver_call = self.mock_object(
              self.share_manager.driver, 'create_replica',
              mock.Mock(return_value=driver_retval))
          self.mock_object(db, 'share_instance_access_get',
                           mock.Mock(return_value=fake_access_rules[0]))
          mock_share_replica_access_update = self.mock_object(
              self.share_manager.access_helper,
              'get_and_update_share_instance_access_rules_status')
  
          self.share_manager.create_share_replica(self.context, replica)
  
          self.assertFalse(mock_replica_update_call.called)
          mock_share_replica_access_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              share_instance_id=replica['id'], status=constants.STATUS_ACTIVE)
          self.assertFalse(mock_export_locs_update_call.called)
          self.assertTrue(mock_log_info.called)
          self.assertTrue(mock_log_warning.called)
          self.assertFalse(mock_log_error.called)
          self.assertTrue(driver_call.called)
          call_args = driver_call.call_args_list[0][0]
          replica_list_arg = call_args[1]
          r_ids = [r['id'] for r in replica_list_arg]
          for r in (replica, replica_2):
              self.assertIn(r['id'], r_ids)
          self.assertEqual(2, len(r_ids))
  
      def test_create_share_replica_no_availability_zone(self):
          replica = fake_replica(
              availability_zone=None, share_network='',
              replica_state=constants.REPLICA_STATE_OUT_OF_SYNC)
          replica_2 = fake_replica(id='fake2')
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica, replica_2]))
          self.share_manager.availability_zone = 'fake_az'
          fake_access_rules = [{'id': '1'}, {'id': '2'}, {'id': '3'}]
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(db, 'share_instance_access_copy',
                           mock.Mock(return_value=fake_access_rules))
          self.mock_object(db, 'share_replicas_get_available_active_replica',
                           mock.Mock(return_value=replica_2))
          self.mock_object(self.share_manager,
                           '_provide_share_server_for_share',
                           mock.Mock(return_value=('FAKE_SERVER', replica)))
          self.mock_object(self.share_manager,
                           '_get_replica_snapshots_for_snapshot',
                           mock.Mock(return_value=[]))
          mock_replica_update_call = self.mock_object(
              db, 'share_replica_update', mock.Mock(return_value=replica))
          mock_calls = [
              mock.call(mock.ANY, replica['id'],
                        {'availability_zone': 'fake_az'}, with_share_data=True),
              mock.call(mock.ANY, replica['id'],
                        {'status': constants.STATUS_AVAILABLE,
                         'replica_state': constants.REPLICA_STATE_OUT_OF_SYNC,
                         'progress': '100%'}),
          ]
          mock_export_locs_update_call = self.mock_object(
              db, 'share_export_locations_update')
          mock_log_info = self.mock_object(manager.LOG, 'info')
          mock_log_warning = self.mock_object(manager.LOG, 'warning')
          mock_log_error = self.mock_object(manager.LOG, 'warning')
          self.mock_object(db, 'share_instance_access_get',
                           mock.Mock(return_value=fake_access_rules[0]))
          mock_share_replica_access_update = self.mock_object(
              self.share_manager, '_update_share_replica_access_rules_state')
          driver_call = self.mock_object(
              self.share_manager.driver, 'create_replica',
              mock.Mock(return_value=replica))
          self.mock_object(self.share_manager, '_get_share_server', mock.Mock())
  
          self.share_manager.create_share_replica(self.context, replica)
  
          mock_replica_update_call.assert_has_calls(mock_calls, any_order=False)
          mock_share_replica_access_update.assert_called_once_with(
              mock.ANY, replica['id'], replica['access_rules_status'])
          self.assertTrue(mock_export_locs_update_call.called)
          self.assertTrue(mock_log_info.called)
          self.assertFalse(mock_log_warning.called)
          self.assertFalse(mock_log_error.called)
          self.assertTrue(driver_call.called)
  
      @ddt.data(True, False)
      def test_create_share_replica(self, has_snapshots):
          replica = fake_replica(
              share_network='', replica_state=constants.REPLICA_STATE_IN_SYNC)
          replica_2 = fake_replica(id='fake2')
          snapshots = ([fakes.fake_snapshot(create_instance=True)]
                       if has_snapshots else [])
          snapshot_instances = [
              fakes.fake_snapshot_instance(share_instance_id=replica['id']),
              fakes.fake_snapshot_instance(share_instance_id='fake2'),
          ]
          fake_access_rules = [{'id': '1'}, {'id': '2'}, {'id': '3'}]
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(db, 'share_instance_access_copy',
                           mock.Mock(return_value=fake_access_rules))
          self.mock_object(db, 'share_replicas_get_available_active_replica',
                           mock.Mock(return_value=replica_2))
          self.mock_object(self.share_manager,
                           '_provide_share_server_for_share',
                           mock.Mock(return_value=('FAKE_SERVER', replica)))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica, replica_2]))
          self.mock_object(db, 'share_snapshot_get_all_for_share', mock.Mock(
              return_value=snapshots))
          mock_instance_get_call = self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(return_value=snapshot_instances))
  
          mock_replica_update_call = self.mock_object(db, 'share_replica_update')
          mock_export_locs_update_call = self.mock_object(
              db, 'share_export_locations_update')
          mock_log_info = self.mock_object(manager.LOG, 'info')
          mock_log_warning = self.mock_object(manager.LOG, 'warning')
          mock_log_error = self.mock_object(manager.LOG, 'warning')
          self.mock_object(db, 'share_instance_access_get',
                           mock.Mock(return_value=fake_access_rules[0]))
          mock_share_replica_access_update = self.mock_object(
              self.share_manager.access_helper,
              'get_and_update_share_instance_access_rules_status')
          driver_call = self.mock_object(
              self.share_manager.driver, 'create_replica',
              mock.Mock(return_value=replica))
          self.mock_object(self.share_manager, '_get_share_server')
  
          self.share_manager.create_share_replica(self.context, replica)
  
          mock_replica_update_call.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), replica['id'],
              {'status': constants.STATUS_AVAILABLE,
               'replica_state': constants.REPLICA_STATE_IN_SYNC,
               'progress': '100%'})
          mock_share_replica_access_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              share_instance_id=replica['id'],
              status=replica['access_rules_status'])
          self.assertTrue(mock_export_locs_update_call.called)
          self.assertTrue(mock_log_info.called)
          self.assertFalse(mock_log_warning.called)
          self.assertFalse(mock_log_error.called)
          self.assertTrue(driver_call.called)
          call_args = driver_call.call_args_list[0][0]
          replica_list_arg = call_args[1]
          snapshot_list_arg = call_args[4]
          r_ids = [r['id'] for r in replica_list_arg]
          for r in (replica, replica_2):
              self.assertIn(r['id'], r_ids)
          self.assertEqual(2, len(r_ids))
          if has_snapshots:
              for snapshot_dict in snapshot_list_arg:
                  self.assertIn('active_replica_snapshot', snapshot_dict)
                  self.assertIn('share_replica_snapshot', snapshot_dict)
          else:
              self.assertFalse(mock_instance_get_call.called)
  
      def test_delete_share_replica_access_rules_exception(self):
          replica = fake_replica()
          replica_2 = fake_replica(id='fake_2')
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica, replica_2]))
          active_replica = fake_replica(
              id='Current_active_replica',
              replica_state=constants.REPLICA_STATE_ACTIVE)
          mock_exception_log = self.mock_object(manager.LOG, 'exception')
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(db, 'share_replicas_get_available_active_replica',
                           mock.Mock(return_value=active_replica))
          self.mock_object(self.share_manager, '_get_share_server')
          self.mock_object(self.share_manager.access_helper,
                           'update_access_rules')
          mock_replica_update_call = self.mock_object(db, 'share_replica_update')
          mock_replica_delete_call = self.mock_object(db, 'share_replica_delete')
          mock_drv_delete_replica_call = self.mock_object(
              self.share_manager.driver, 'delete_replica')
          self.mock_object(
              self.share_manager.access_helper, 'update_access_rules',
              mock.Mock(side_effect=exception.ManilaException))
  
          self.assertRaises(exception.ManilaException,
                            self.share_manager.delete_share_replica,
                            self.context, replica['id'],
                            share_id=replica['share_id'])
          mock_replica_update_call.assert_called_once_with(
              mock.ANY, replica['id'], {'status': constants.STATUS_ERROR})
          self.assertFalse(mock_drv_delete_replica_call.called)
          self.assertFalse(mock_replica_delete_call.called)
          self.assertFalse(mock_exception_log.called)
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.DELETE_ACCESS_RULES,
              replica['project_id'],
              resource_type=message_field.Resource.SHARE_REPLICA,
              resource_id=replica['id'],
              exception=mock.ANY)
  
      def test_delete_share_replica_drv_misbehavior_ignored_with_the_force(self):
          replica = fake_replica()
          active_replica = fake_replica(id='Current_active_replica')
          mock_exception_log = self.mock_object(manager.LOG, 'exception')
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica, active_replica]))
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(db, 'share_replicas_get_available_active_replica',
                           mock.Mock(return_value=active_replica))
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=None))
          self.mock_object(self.share_manager.access_helper,
                           'update_access_rules')
          self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(return_value=[]))
          mock_snap_instance_delete = self.mock_object(
              db, 'share_snapshot_instance_delete')
          mock_replica_update_call = self.mock_object(db, 'share_replica_update')
          mock_replica_delete_call = self.mock_object(db, 'share_replica_delete')
          mock_drv_delete_replica_call = self.mock_object(
              self.share_manager.driver, 'delete_replica',
              mock.Mock(side_effect=exception.ManilaException))
          self.mock_object(
              self.share_manager.access_helper, 'update_access_rules')
  
          self.share_manager.delete_share_replica(
              self.context, replica['id'], share_id=replica['share_id'],
              force=True)
  
          self.assertFalse(mock_replica_update_call.called)
          self.assertTrue(mock_replica_delete_call.called)
          self.assertEqual(1, mock_exception_log.call_count)
          self.assertTrue(mock_drv_delete_replica_call.called)
          self.assertFalse(mock_snap_instance_delete.called)
  
      def test_delete_share_replica_driver_exception(self):
          replica = fake_replica()
          active_replica = fake_replica(id='Current_active_replica')
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica, active_replica]))
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(db, 'share_replicas_get_available_active_replica',
                           mock.Mock(return_value=active_replica))
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=None))
          mock_snapshot_get_call = self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(return_value=[]))
          mock_replica_update_call = self.mock_object(db, 'share_replica_update')
          mock_replica_delete_call = self.mock_object(db, 'share_replica_delete')
          self.mock_object(
              self.share_manager.access_helper, 'update_access_rules')
          mock_drv_delete_replica_call = self.mock_object(
              self.share_manager.driver, 'delete_replica',
              mock.Mock(side_effect=exception.ManilaException))
  
          self.assertRaises(exception.ManilaException,
                            self.share_manager.delete_share_replica,
                            self.context, replica['id'],
                            share_id=replica['share_id'])
          self.assertTrue(mock_replica_update_call.called)
          self.assertFalse(mock_replica_delete_call.called)
          self.assertTrue(mock_drv_delete_replica_call.called)
          self.assertTrue(mock_snapshot_get_call.called)
  
      def test_delete_share_replica_both_exceptions_ignored_with_the_force(self):
          replica = fake_replica()
          active_replica = fake_replica(id='Current_active_replica')
          snapshots = [
              fakes.fake_snapshot(share_id=replica['id'],
                                  status=constants.STATUS_AVAILABLE),
              fakes.fake_snapshot(share_id=replica['id'],
                                  id='test_creating_to_err',
                                  status=constants.STATUS_CREATING)
          ]
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica, active_replica]))
          mock_exception_log = self.mock_object(manager.LOG, 'exception')
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(db, 'share_replicas_get_available_active_replica',
                           mock.Mock(return_value=active_replica))
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=None))
          self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(return_value=snapshots))
          mock_snapshot_instance_delete_call = self.mock_object(
              db, 'share_snapshot_instance_delete')
          mock_replica_update_call = self.mock_object(db, 'share_replica_update')
          mock_replica_delete_call = self.mock_object(db, 'share_replica_delete')
          self.mock_object(
              self.share_manager.access_helper, 'update_access_rules',
              mock.Mock(side_effect=exception.ManilaException))
          mock_drv_delete_replica_call = self.mock_object(
              self.share_manager.driver, 'delete_replica',
              mock.Mock(side_effect=exception.ManilaException))
  
          self.share_manager.delete_share_replica(
              self.context, replica['id'], share_id=replica['share_id'],
              force=True)
  
          mock_replica_update_call.assert_called_once_with(
              mock.ANY, replica['id'], {'status': constants.STATUS_ERROR})
          self.assertTrue(mock_replica_delete_call.called)
          self.assertEqual(2, mock_exception_log.call_count)
          self.assertTrue(mock_drv_delete_replica_call.called)
          self.assertEqual(2, mock_snapshot_instance_delete_call.call_count)
  
      def test_delete_share_replica(self):
          replica = fake_replica()
          active_replica = fake_replica(id='current_active_replica')
          snapshots = [
              fakes.fake_snapshot(share_id=replica['share_id'],
                                  status=constants.STATUS_AVAILABLE),
              fakes.fake_snapshot(share_id=replica['share_id'],
                                  id='test_creating_to_err',
                                  status=constants.STATUS_CREATING)
          ]
          self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(return_value=snapshots))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica, active_replica]))
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(db, 'share_replicas_get_available_active_replica',
                           mock.Mock(return_value=active_replica))
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=None))
          mock_info_log = self.mock_object(manager.LOG, 'info')
          mock_snapshot_instance_delete_call = self.mock_object(
              db, 'share_snapshot_instance_delete')
          mock_replica_update_call = self.mock_object(db, 'share_replica_update')
          mock_replica_delete_call = self.mock_object(db, 'share_replica_delete')
          self.mock_object(
              self.share_manager.access_helper, 'update_access_rules')
          mock_drv_delete_replica_call = self.mock_object(
              self.share_manager.driver, 'delete_replica')
  
          self.share_manager.delete_share_replica(self.context, replica)
  
          self.assertFalse(mock_replica_update_call.called)
          self.assertTrue(mock_replica_delete_call.called)
          self.assertTrue(mock_info_log.called)
          self.assertTrue(mock_drv_delete_replica_call.called)
          self.assertEqual(2, mock_snapshot_instance_delete_call.call_count)
  
      def test_promote_share_replica_no_active_replica(self):
          replica = fake_replica()
          replica_list = [replica]
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(self.share_manager, '_get_share_server')
          self.mock_object(db, 'share_replicas_get_available_active_replica',
                           mock.Mock(return_value=replica_list))
          mock_info_log = self.mock_object(manager.LOG, 'info')
          mock_driver_call = self.mock_object(self.share_manager.driver,
                                              'promote_replica')
          mock_replica_update = self.mock_object(db, 'share_replica_update')
          expected_update_call = mock.call(
              mock.ANY, replica['id'], {'status': constants.STATUS_AVAILABLE})
  
          self.assertRaises(exception.ReplicationException,
                            self.share_manager.promote_share_replica,
                            self.context, replica)
          self.assertFalse(mock_info_log.called)
          self.assertFalse(mock_driver_call.called)
          mock_replica_update.assert_has_calls([expected_update_call])
  
      def test_promote_share_replica_driver_exception(self):
          replica = fake_replica()
          active_replica = fake_replica(
              id='current_active_replica',
              replica_state=constants.REPLICA_STATE_ACTIVE)
          replica_list = [replica, active_replica]
          self.mock_object(db, 'share_access_get_all_for_share',
                           mock.Mock(return_value=[]))
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(self.share_manager, '_get_share_server')
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=replica_list))
          self.mock_object(self.share_manager.driver, 'promote_replica',
                           mock.Mock(side_effect=exception.ManilaException))
          mock_info_log = self.mock_object(manager.LOG, 'info')
          mock_replica_update = self.mock_object(db, 'share_replica_update')
          expected_update_calls = [mock.call(
              mock.ANY, r['id'], {'status': constants.STATUS_ERROR})
              for r in (replica, active_replica)]
  
          self.assertRaises(exception.ManilaException,
                            self.share_manager.promote_share_replica,
                            self.context, replica)
          mock_replica_update.assert_has_calls(expected_update_calls)
          self.assertFalse(mock_info_log.called)
  
          expected_message_calls = [
              mock.call(
                  utils.IsAMatcher(context.RequestContext),
                  message_field.Action.PROMOTE,
                  r['project_id'],
                  resource_type=message_field.Resource.SHARE_REPLICA,
                  resource_id=r['id'],
                  exception=mock.ANY)
              for r in (replica, active_replica)]
          self.share_manager.message_api.create.assert_has_calls(
              expected_message_calls)
  
      @ddt.data([], None)
      def test_promote_share_replica_driver_update_nothing_has_snaps(self,
                                                                     retval):
          replica = fake_replica(
              replication_type=constants.REPLICATION_TYPE_READABLE)
          active_replica = fake_replica(
              id='current_active_replica',
              replica_state=constants.REPLICA_STATE_ACTIVE)
          snapshots_instances = [
              fakes.fake_snapshot(create_instance=True,
                                  share_id=replica['share_id'],
                                  status=constants.STATUS_AVAILABLE),
              fakes.fake_snapshot(create_instance=True,
                                  share_id=replica['share_id'],
                                  id='test_creating_to_err',
                                  status=constants.STATUS_CREATING)
          ]
          replica_list = [replica, active_replica]
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(db, 'share_access_get_all_for_share',
                           mock.Mock(return_value=[]))
          self.mock_object(self.share_manager, '_get_share_server')
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=replica_list))
          self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(return_value=snapshots_instances))
          self.mock_object(
              self.share_manager.driver, 'promote_replica',
              mock.Mock(return_value=retval))
          mock_snap_instance_update = self.mock_object(
              db, 'share_snapshot_instance_update')
          mock_info_log = self.mock_object(manager.LOG, 'info')
          mock_export_locs_update = self.mock_object(
              db, 'share_export_locations_update')
          mock_replica_update = self.mock_object(db, 'share_replica_update')
          call_1 = mock.call(mock.ANY, replica['id'],
                             {'status': constants.STATUS_AVAILABLE,
                              'replica_state': constants.REPLICA_STATE_ACTIVE,
                              'cast_rules_to_readonly': False})
          call_2 = mock.call(
              mock.ANY, 'current_active_replica',
              {'replica_state': constants.REPLICA_STATE_OUT_OF_SYNC,
               'cast_rules_to_readonly': True})
          expected_update_calls = [call_1, call_2]
  
          self.share_manager.promote_share_replica(self.context, replica)
  
          self.assertFalse(mock_export_locs_update.called)
          mock_replica_update.assert_has_calls(expected_update_calls,
                                               any_order=True)
          mock_snap_instance_update.assert_called_once_with(
              mock.ANY, 'test_creating_to_err',
              {'status': constants.STATUS_ERROR})
          self.assertEqual(2, mock_info_log.call_count)
  
      @ddt.data(constants.REPLICATION_TYPE_READABLE,
                constants.REPLICATION_TYPE_WRITABLE,
                constants.REPLICATION_TYPE_DR)
      def test_promote_share_replica_driver_updates_replica_list(self, rtype):
          replica = fake_replica(replication_type=rtype)
          active_replica = fake_replica(
              id='current_active_replica',
              replica_state=constants.REPLICA_STATE_ACTIVE)
          replica_list = [
              replica, active_replica, fake_replica(id=3),
              fake_replica(id='one_more_replica'),
          ]
          updated_replica_list = [
              {
                  'id': replica['id'],
                  'export_locations': ['TEST1', 'TEST2'],
                  'replica_state': constants.REPLICA_STATE_ACTIVE,
              },
              {
                  'id': 'current_active_replica',
                  'export_locations': 'junk_return_value',
                  'replica_state': constants.REPLICA_STATE_IN_SYNC,
              },
              {
                  'id': 'other_replica',
                  'export_locations': ['TEST3', 'TEST4'],
              },
              {
                  'id': replica_list[3]['id'],
                  'export_locations': ['TEST5', 'TEST6'],
                  'replica_state': constants.REPLICA_STATE_IN_SYNC,
              },
          ]
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(return_value=[]))
          self.mock_object(db, 'share_access_get_all_for_share',
                           mock.Mock(return_value=[]))
          self.mock_object(self.share_manager, '_get_share_server')
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=replica_list))
          mock_snap_instance_update = self.mock_object(
              db, 'share_snapshot_instance_update')
          self.mock_object(
              self.share_manager.driver, 'promote_replica',
              mock.Mock(return_value=updated_replica_list))
          mock_info_log = self.mock_object(manager.LOG, 'info')
          mock_export_locs_update = self.mock_object(
              db, 'share_export_locations_update')
          mock_replica_update = self.mock_object(db, 'share_replica_update')
          reset_replication_change_updates = {
              'replica_state': constants.STATUS_ACTIVE,
              'status': constants.STATUS_AVAILABLE,
              'cast_rules_to_readonly': False,
          }
          demoted_replica_updates = {
              'replica_state': constants.REPLICA_STATE_IN_SYNC,
              'cast_rules_to_readonly': False,
          }
          if rtype == constants.REPLICATION_TYPE_READABLE:
              demoted_replica_updates['cast_rules_to_readonly'] = True
          reset_replication_change_call = mock.call(
              mock.ANY, replica['id'], reset_replication_change_updates)
          demoted_replica_update_call = mock.call(
              mock.ANY, active_replica['id'], demoted_replica_updates
          )
          additional_replica_update_call = mock.call(
              mock.ANY, replica_list[3]['id'], {
                  'replica_state': constants.REPLICA_STATE_IN_SYNC,
              }
          )
  
          self.share_manager.promote_share_replica(self.context, replica)
  
          self.assertEqual(3, mock_export_locs_update.call_count)
          mock_replica_update.assert_has_calls([
              demoted_replica_update_call,
              additional_replica_update_call,
              reset_replication_change_call,
          ])
          self.assertTrue(mock_info_log.called)
          self.assertFalse(mock_snap_instance_update.called)
  
      @ddt.data('openstack1@watson#_pool0', 'openstack1@newton#_pool0')
      def test_periodic_share_replica_update(self, host):
          mock_debug_log = self.mock_object(manager.LOG, 'debug')
          replicas = [
              fake_replica(host='openstack1@watson#pool4'),
              fake_replica(host='openstack1@watson#pool5'),
              fake_replica(host='openstack1@newton#pool5'),
              fake_replica(host='openstack1@newton#pool5'),
  
          ]
          self.mock_object(self.share_manager.db, 'share_replicas_get_all',
                           mock.Mock(return_value=replicas))
          mock_update_method = self.mock_object(
              self.share_manager, '_share_replica_update')
  
          self.share_manager.host = host
  
          self.share_manager.periodic_share_replica_update(self.context)
  
          self.assertEqual(2, mock_update_method.call_count)
          self.assertEqual(1, mock_debug_log.call_count)
  
      @ddt.data(constants.REPLICA_STATE_IN_SYNC,
                constants.REPLICA_STATE_OUT_OF_SYNC)
      def test__share_replica_update_driver_exception(self, replica_state):
          mock_debug_log = self.mock_object(manager.LOG, 'debug')
          replica = fake_replica(replica_state=replica_state)
          active_replica = fake_replica(
              replica_state=constants.REPLICA_STATE_ACTIVE)
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica, active_replica]))
          self.mock_object(self.share_manager.db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(db, 'share_server_get',
                           mock.Mock(return_value=fakes.fake_share_server_get()))
          self.mock_object(self.share_manager.driver, 'update_replica_state',
                           mock.Mock(side_effect=exception.ManilaException))
          mock_db_update_call = self.mock_object(
              self.share_manager.db, 'share_replica_update')
  
          self.share_manager._share_replica_update(
              self.context, replica, share_id=replica['share_id'])
  
          mock_db_update_call.assert_called_once_with(
              self.context, replica['id'],
              {'replica_state': constants.STATUS_ERROR,
               'status': constants.STATUS_ERROR}
          )
          self.assertEqual(1, mock_debug_log.call_count)
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.UPDATE,
              replica['project_id'],
              resource_type=message_field.Resource.SHARE_REPLICA,
              resource_id=replica['id'],
              exception=mock.ANY)
  
      def test__share_replica_update_driver_exception_ignored(self):
          mock_debug_log = self.mock_object(manager.LOG, 'debug')
          replica = fake_replica(replica_state=constants.STATUS_ERROR)
          active_replica = fake_replica(replica_state=constants.STATUS_ACTIVE)
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica, active_replica]))
          self.mock_object(self.share_manager.db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          self.mock_object(db, 'share_server_get',
                           mock.Mock(return_value={}))
          self.share_manager.host = replica['host']
          self.mock_object(self.share_manager.driver, 'update_replica_state',
                           mock.Mock(side_effect=exception.ManilaException))
          mock_db_update_call = self.mock_object(
              self.share_manager.db, 'share_replica_update')
  
          self.share_manager._share_replica_update(
              self.context, replica, share_id=replica['share_id'])
  
          mock_db_update_call.assert_called_once_with(
              self.context, replica['id'],
              {'replica_state': constants.STATUS_ERROR,
               'status': constants.STATUS_ERROR}
          )
          self.assertEqual(1, mock_debug_log.call_count)
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.UPDATE,
              replica['project_id'],
              resource_type=message_field.Resource.SHARE_REPLICA,
              resource_id=replica['id'],
              exception=mock.ANY)
  
      @ddt.data({'status': constants.STATUS_AVAILABLE,
                 'replica_state': constants.REPLICA_STATE_ACTIVE, },
                {'status': constants.STATUS_DELETING,
                 'replica_state': constants.REPLICA_STATE_IN_SYNC, },
                {'status': constants.STATUS_CREATING,
                 'replica_state': constants.REPLICA_STATE_OUT_OF_SYNC, },
                {'status': constants.STATUS_MANAGING,
                 'replica_state': constants.REPLICA_STATE_OUT_OF_SYNC, },
                {'status': constants.STATUS_UNMANAGING,
                 'replica_state': constants.REPLICA_STATE_ACTIVE, },
                {'status': constants.STATUS_EXTENDING,
                 'replica_state': constants.REPLICA_STATE_IN_SYNC, },
                {'status': constants.STATUS_SHRINKING,
                 'replica_state': constants.REPLICA_STATE_IN_SYNC, })
      def test__share_replica_update_unqualified_replica(self, state):
          mock_debug_log = self.mock_object(manager.LOG, 'debug')
          mock_warning_log = self.mock_object(manager.LOG, 'warning')
          mock_driver_call = self.mock_object(
              self.share_manager.driver, 'update_replica_state')
          mock_db_update_call = self.mock_object(
              self.share_manager.db, 'share_replica_update')
          replica = fake_replica(**state)
          self.mock_object(db, 'share_server_get',
                           mock.Mock(return_value='fake_share_server'))
          self.mock_object(db, 'share_replica_get',
                           mock.Mock(return_value=replica))
  
          self.share_manager._share_replica_update(self.context, replica,
                                                   share_id=replica['share_id'])
  
          self.assertFalse(mock_debug_log.called)
          self.assertFalse(mock_warning_log.called)
          self.assertFalse(mock_driver_call.called)
          self.assertFalse(mock_db_update_call.called)
  
      @ddt.data(None, constants.REPLICA_STATE_IN_SYNC,
                constants.REPLICA_STATE_OUT_OF_SYNC,
                constants.REPLICA_STATE_ACTIVE,
                constants.STATUS_ERROR)
      def test__share_replica_update(self, retval):
          mock_debug_log = self.mock_object(manager.LOG, 'debug')
          mock_warning_log = self.mock_object(manager.LOG, 'warning')
          replica_states = [constants.REPLICA_STATE_IN_SYNC,
                            constants.REPLICA_STATE_OUT_OF_SYNC]
          replica = fake_replica(replica_state=random.choice(replica_states),
                                 share_server=fakes.fake_share_server_get())
          active_replica = fake_replica(
              id='fake2', replica_state=constants.STATUS_ACTIVE)
          snapshots = [fakes.fake_snapshot(
              create_instance=True, aggregate_status=constants.STATUS_AVAILABLE)]
          snapshot_instances = [
              fakes.fake_snapshot_instance(share_instance_id=replica['id']),
              fakes.fake_snapshot_instance(share_instance_id='fake2'),
          ]
          del replica['availability_zone']
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica, active_replica]))
          self.mock_object(db, 'share_server_get',
                           mock.Mock(return_value=fakes.fake_share_server_get()))
          mock_db_update_calls = []
          self.mock_object(self.share_manager.db, 'share_replica_get',
                           mock.Mock(return_value=replica))
          mock_driver_call = self.mock_object(
              self.share_manager.driver, 'update_replica_state',
              mock.Mock(return_value=retval))
          mock_db_update_call = self.mock_object(
              self.share_manager.db, 'share_replica_update')
          self.mock_object(db, 'share_snapshot_get_all_for_share',
                           mock.Mock(return_value=snapshots))
          self.mock_object(db, 'share_snapshot_instance_get_all_with_filters',
                           mock.Mock(return_value=snapshot_instances))
  
          self.share_manager._share_replica_update(
              self.context, replica, share_id=replica['share_id'])
  
          if retval == constants.REPLICA_STATE_ACTIVE:
              self.assertEqual(1, mock_warning_log.call_count)
          elif retval:
              self.assertEqual(0, mock_warning_log.call_count)
          self.assertTrue(mock_driver_call.called)
          # pylint: disable=unsubscriptable-object
          snapshot_list_arg = mock_driver_call.call_args[0][4]
          # pylint: enable=unsubscriptable-object
          self.assertIn('active_replica_snapshot', snapshot_list_arg[0])
          self.assertIn('share_replica_snapshot', snapshot_list_arg[0])
          mock_db_update_call.assert_has_calls(mock_db_update_calls)
          self.assertEqual(1, mock_debug_log.call_count)
  
      def test_update_share_replica_replica_not_found(self):
          replica = fake_replica()
          self.mock_object(
              self.share_manager.db, 'share_replica_get', mock.Mock(
                  side_effect=exception.ShareReplicaNotFound(replica_id='fake')))
          self.mock_object(self.share_manager, '_get_share_server')
          driver_call = self.mock_object(
              self.share_manager, '_share_replica_update')
  
          self.assertRaises(
              exception.ShareReplicaNotFound,
              self.share_manager.update_share_replica,
              self.context, replica, share_id=replica['share_id'])
  
          self.assertFalse(driver_call.called)
  
      def test_update_share_replica_replica(self):
          replica_update_call = self.mock_object(
              self.share_manager, '_share_replica_update')
          self.mock_object(self.share_manager.db, 'share_replica_get')
  
          retval = self.share_manager.update_share_replica(
              self.context, 'fake_replica_id', share_id='fake_share_id')
  
          self.assertIsNone(retval)
          self.assertTrue(replica_update_call.called)
  
      def _get_snapshot_instance_dict(self, snapshot_instance, share,
                                      snapshot=None):
          expected_snapshot_instance_dict = {
              'status': constants.STATUS_CREATING,
              'share_id': share['id'],
              'share_name': snapshot_instance['share_name'],
              'deleted': snapshot_instance['deleted'],
              'share': share,
              'updated_at': snapshot_instance['updated_at'],
              'snapshot_id': snapshot_instance['snapshot_id'],
              'id': snapshot_instance['id'],
              'name': snapshot_instance['name'],
              'created_at': snapshot_instance['created_at'],
              'share_instance_id': snapshot_instance['share_instance_id'],
              'progress': snapshot_instance['progress'],
              'deleted_at': snapshot_instance['deleted_at'],
              'provider_location': snapshot_instance['provider_location'],
          }
          if snapshot:
              expected_snapshot_instance_dict.update({
                  'size': snapshot['size'],
              })
          return expected_snapshot_instance_dict
  
      def test_create_snapshot_driver_exception(self):
  
          def _raise_not_found(self, *args, **kwargs):
              raise exception.NotFound()
  
          share_id = 'FAKE_SHARE_ID'
          share = fakes.fake_share(id=share_id, instance={'id': 'fake_id'})
          snapshot_instance = fakes.fake_snapshot_instance(
              share_id=share_id, share=share, name='fake_snapshot')
          snapshot = fakes.fake_snapshot(
              share_id=share_id, share=share, instance=snapshot_instance,
              project_id=self.context.project_id)
          snapshot_id = snapshot['id']
          self.mock_object(self.share_manager.driver, "create_snapshot",
                           mock.Mock(side_effect=_raise_not_found))
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=None))
          self.mock_object(self.share_manager.db, 'share_snapshot_instance_get',
                           mock.Mock(return_value=snapshot_instance))
          self.mock_object(self.share_manager.db, 'share_snapshot_get',
                           mock.Mock(return_value=snapshot))
          db_update = self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_update')
          expected_snapshot_instance_dict = self._get_snapshot_instance_dict(
              snapshot_instance, share)
  
          self.assertRaises(exception.NotFound,
                            self.share_manager.create_snapshot,
                            self.context, share_id, snapshot_id)
          db_update.assert_called_once_with(self.context,
                                            snapshot_instance['id'],
                                            {'status': constants.STATUS_ERROR})
  
          self.share_manager.driver.create_snapshot.assert_called_once_with(
              self.context, expected_snapshot_instance_dict, share_server=None)
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.CREATE,
              snapshot['project_id'],
              resource_type=message_field.Resource.SHARE_SNAPSHOT,
              resource_id=snapshot_instance['id'],
              exception=mock.ANY)
  
      @ddt.data({'model_update': {}, 'mount_snapshot_support': True},
                {'model_update': {}, 'mount_snapshot_support': False},
                {'model_update': {'export_locations': [
                    {'path': '/path1', 'is_admin_only': True},
                    {'path': '/path2', 'is_admin_only': False}
                ]}, 'mount_snapshot_support': True},
                {'model_update': {'export_locations': [
                    {'path': '/path1', 'is_admin_only': True},
                    {'path': '/path2', 'is_admin_only': False}
                ]}, 'mount_snapshot_support': False})
      @ddt.unpack
      def test_create_snapshot(self, model_update, mount_snapshot_support):
          export_locations = model_update.get('export_locations')
          share_id = 'FAKE_SHARE_ID'
          share = fakes.fake_share(
              id=share_id,
              instance={'id': 'fake_id'},
              mount_snapshot_support=mount_snapshot_support)
          snapshot_instance = fakes.fake_snapshot_instance(
              share_id=share_id, share=share, name='fake_snapshot')
          snapshot = fakes.fake_snapshot(
              share_id=share_id, share=share, instance=snapshot_instance)
          snapshot_id = snapshot['id']
          self.mock_object(self.share_manager.db, 'share_snapshot_get',
                           mock.Mock(return_value=snapshot))
          self.mock_object(self.share_manager.db, 'share_snapshot_instance_get',
                           mock.Mock(return_value=snapshot_instance))
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=None))
          mock_export_update = self.mock_object(
              self.share_manager.db,
              'share_snapshot_instance_export_location_create')
          expected_update_calls = [
              mock.call(self.context, snapshot_instance['id'],
                        {'status': constants.STATUS_AVAILABLE,
                         'progress': '100%'})
          ]
  
          expected_snapshot_instance_dict = self._get_snapshot_instance_dict(
              snapshot_instance, share)
  
          self.mock_object(
              self.share_manager.driver, 'create_snapshot',
              mock.Mock(return_value=model_update))
          db_update = self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_update')
  
          return_value = self.share_manager.create_snapshot(
              self.context, share_id, snapshot_id)
  
          self.assertIsNone(return_value)
          self.share_manager.driver.create_snapshot.assert_called_once_with(
              self.context, expected_snapshot_instance_dict, share_server=None)
          db_update.assert_has_calls(expected_update_calls, any_order=True)
          if mount_snapshot_support and export_locations:
              snap_ins_id = snapshot.instance['id']
              for i in range(0, 2):
                  export_locations[i]['share_snapshot_instance_id'] = snap_ins_id
              mock_export_update.assert_has_calls([
                  mock.call(utils.IsAMatcher(context.RequestContext),
                            export_locations[0]),
                  mock.call(utils.IsAMatcher(context.RequestContext),
                            export_locations[1]),
              ])
          else:
              mock_export_update.assert_not_called()
  
      @ddt.data(exception.ShareSnapshotIsBusy(snapshot_name='fake_name'),
                exception.NotFound())
      def test_delete_snapshot_driver_exception(self, exc):
  
          share_id = 'FAKE_SHARE_ID'
          share = fakes.fake_share(id=share_id, instance={'id': 'fake_id'},
                                   mount_snapshot_support=True)
          snapshot_instance = fakes.fake_snapshot_instance(
              share_id=share_id, share=share, name='fake_snapshot')
          snapshot = fakes.fake_snapshot(
              share_id=share_id, share=share, instance=snapshot_instance,
              project_id=self.context.project_id)
          snapshot_id = snapshot['id']
  
          update_access = self.mock_object(
              self.share_manager.snapshot_access_helper, 'update_access_rules')
          self.mock_object(self.share_manager.driver, "delete_snapshot",
                           mock.Mock(side_effect=exc))
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=None))
          self.mock_object(self.share_manager.db, 'share_snapshot_instance_get',
                           mock.Mock(return_value=snapshot_instance))
          self.mock_object(self.share_manager.db, 'share_snapshot_get',
                           mock.Mock(return_value=snapshot))
          self.mock_object(
              self.share_manager.db, 'share_get', mock.Mock(return_value=share))
          db_update = self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_update')
          db_destroy_call = self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_delete')
          expected_snapshot_instance_dict = self._get_snapshot_instance_dict(
              snapshot_instance, share)
          mock_exception_log = self.mock_object(manager.LOG, 'exception')
          self.assertRaises(type(exc), self.share_manager.delete_snapshot,
                            self.context, snapshot_id)
          db_update.assert_called_once_with(
              mock.ANY, snapshot_instance['id'],
              {'status': constants.STATUS_ERROR_DELETING})
          self.share_manager.driver.delete_snapshot.assert_called_once_with(
              mock.ANY, expected_snapshot_instance_dict,
              share_server=None)
          update_access.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              snapshot_instance['id'], delete_all_rules=True, share_server=None)
          self.assertFalse(db_destroy_call.called)
          self.assertFalse(mock_exception_log.called)
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.DELETE,
              snapshot['project_id'],
              resource_type=message_field.Resource.SHARE_SNAPSHOT,
              resource_id=snapshot_instance['id'],
              exception=mock.ANY)
  
      @ddt.data(True, False)
      def test_delete_snapshot_with_quota_error(self, quota_error):
  
          share_id = 'FAKE_SHARE_ID'
          share = fakes.fake_share(id=share_id)
          snapshot_instance = fakes.fake_snapshot_instance(
              share_id=share_id, share=share, name='fake_snapshot')
          snapshot = fakes.fake_snapshot(
              share_id=share_id, share=share, instance=snapshot_instance,
              project_id=self.context.project_id, size=1)
          snapshot_id = snapshot['id']
          self.mock_object(self.share_manager.db, 'share_snapshot_get',
                           mock.Mock(return_value=snapshot))
          self.mock_object(self.share_manager.db, 'share_snapshot_instance_get',
                           mock.Mock(return_value=snapshot_instance))
          self.mock_object(self.share_manager.db, 'share_get',
                           mock.Mock(return_value=share))
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=None))
          mock_exception_log = self.mock_object(manager.LOG, 'exception')
          expected_exc_count = 1 if quota_error else 0
  
          expected_snapshot_instance_dict = self._get_snapshot_instance_dict(
              snapshot_instance, share)
  
          self.mock_object(self.share_manager.driver, 'delete_snapshot')
          db_update_call = self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_update')
          snapshot_destroy_call = self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_delete')
          side_effect = exception.QuotaError(code=500) if quota_error else None
          self.mock_object(quota.QUOTAS, 'reserve',
                           mock.Mock(side_effect=side_effect))
          quota_commit_call = self.mock_object(quota.QUOTAS, 'commit')
  
          retval = self.share_manager.delete_snapshot(
              self.context, snapshot_id)
  
          self.assertIsNone(retval)
          self.share_manager.driver.delete_snapshot.assert_called_once_with(
              mock.ANY, expected_snapshot_instance_dict, share_server=None)
          self.assertFalse(db_update_call.called)
          self.assertTrue(snapshot_destroy_call.called)
          self.assertTrue(manager.QUOTAS.reserve.called)
          quota.QUOTAS.reserve.assert_called_once_with(
              mock.ANY, project_id=self.context.project_id, snapshots=-1,
              snapshot_gigabytes=-snapshot['size'], user_id=snapshot['user_id'],
              share_type_id=share['instance']['share_type_id'])
          self.assertEqual(not quota_error, quota_commit_call.called)
          self.assertEqual(quota_error, mock_exception_log.called)
          self.assertEqual(expected_exc_count, mock_exception_log.call_count)
  
      @ddt.data(exception.ShareSnapshotIsBusy, exception.ManilaException)
      def test_delete_snapshot_ignore_exceptions_with_the_force(self, exc):
  
          def _raise_quota_error():
              raise exception.QuotaError(code='500')
  
          share_id = 'FAKE_SHARE_ID'
          share = fakes.fake_share(id=share_id)
          snapshot_instance = fakes.fake_snapshot_instance(
              share_id=share_id, share=share, name='fake_snapshot')
          snapshot = fakes.fake_snapshot(
              share_id=share_id, share=share, instance=snapshot_instance,
              project_id=self.context.project_id, size=1)
          snapshot_id = snapshot['id']
          self.mock_object(self.share_manager.db, 'share_snapshot_get',
                           mock.Mock(return_value=snapshot))
          self.mock_object(self.share_manager.db, 'share_snapshot_instance_get',
                           mock.Mock(return_value=snapshot_instance))
          self.mock_object(self.share_manager.db, 'share_get',
                           mock.Mock(return_value=share))
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=None))
          mock_exception_log = self.mock_object(manager.LOG, 'exception')
          self.mock_object(self.share_manager.driver, 'delete_snapshot',
                           mock.Mock(side_effect=exc))
          db_update_call = self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_update')
          snapshot_destroy_call = self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_delete')
          self.mock_object(quota.QUOTAS, 'reserve',
                           mock.Mock(side_effect=_raise_quota_error))
          quota_commit_call = self.mock_object(quota.QUOTAS, 'commit')
  
          retval = self.share_manager.delete_snapshot(
              self.context, snapshot_id, force=True)
  
          self.assertIsNone(retval)
          self.assertEqual(2, mock_exception_log.call_count)
          snapshot_destroy_call.assert_called_once_with(
              mock.ANY, snapshot_instance['id'])
          self.assertFalse(quota_commit_call.called)
          self.assertFalse(db_update_call.called)
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.DELETE,
              snapshot['project_id'],
              resource_type=message_field.Resource.SHARE_SNAPSHOT,
              resource_id=snapshot_instance['id'],
              exception=mock.ANY)
  
      def test_create_share_instance_with_share_network_dhss_false(self):
          manager.CONF.set_default('driver_handles_share_servers', False)
          self.mock_object(
              self.share_manager.driver.configuration, 'safe_get',
              mock.Mock(return_value=False))
          share_network_id = 'fake_sn'
          share = db_utils.create_share(share_network_id=share_network_id)
          share_instance = share.instance
          self.mock_object(
              self.share_manager.db, 'share_instance_get',
              mock.Mock(return_value=share_instance))
          self.mock_object(self.share_manager.db, 'share_instance_update')
  
          self.assertRaisesRegex(
              exception.ManilaException,
              '.*%s.*' % share_instance['id'],
              self.share_manager.create_share_instance, self.context,
              share_instance['id'])
          self.share_manager.db.share_instance_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              share_instance['id'],
              with_share_data=True
          )
          self.share_manager.db.share_instance_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), share_instance['id'],
              {'status': constants.STATUS_ERROR})
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.CREATE,
              six.text_type(share.project_id),
              resource_type=message_field.Resource.SHARE,
              resource_id=share['id'],
              detail=mock.ANY)
  
      def test_create_share_instance_with_share_network_server_not_exists(self):
          """Test share can be created without share server."""
  
          share_net = db_utils.create_share_network()
          share_net_subnet = db_utils.create_share_network_subnet(
              share_network_id=share_net['id'],
              availability_zone_id=None,
          )
          share = db_utils.create_share(share_network_id=share_net['id'])
          share_id = share['id']
  
          def fake_setup_server(context, share_network, *args, **kwargs):
              return db_utils.create_share_server(
                  share_network_subnet_id=share_net_subnet['id'],
                  host='fake_host')
  
          self.mock_object(manager.LOG, 'info')
          self.share_manager.driver.create_share = mock.Mock(
              return_value='fake_location')
          self.share_manager._setup_server = fake_setup_server
          self.share_manager.create_share_instance(self.context,
                                                   share.instance['id'])
          self.assertEqual(share_id, db.share_get(context.get_admin_context(),
                           share_id).id)
          manager.LOG.info.assert_called_with(mock.ANY, share.instance['id'])
  
      def test_create_share_instance_with_share_network_server_fail(self):
          share_network = db_utils.create_share_network(id='fake_sn_id')
          share_net_subnet = db_utils.create_share_network_subnet(
              id='fake_sns_id', share_network_id=share_network['id']
          )
          fake_share = db_utils.create_share(
              share_network_id=share_network['id'], size=1)
          fake_metadata = {
              'request_host': 'fake_host',
              'share_type_id': 'fake_share_type_id',
          }
          fake_server = db_utils.create_share_server(
              id='fake_srv_id', status=constants.STATUS_CREATING)
  
          self.mock_object(self.share_manager, '_build_server_metadata',
                           mock.Mock(return_value=fake_metadata))
          self.mock_object(db, 'share_server_create',
                           mock.Mock(return_value=fake_server))
          self.mock_object(db, 'share_instance_update',
                           mock.Mock(return_value=fake_share.instance))
          self.mock_object(db, 'share_instance_get',
                           mock.Mock(return_value=fake_share.instance))
          self.mock_object(db,
                           'share_network_subnet_get_by_availability_zone_id',
                           mock.Mock(return_value=share_net_subnet))
          self.mock_object(manager.LOG, 'warning')
  
          def raise_share_server_not_found(*args, **kwargs):
              raise exception.ShareServerNotFound(
                  share_server_id=fake_server['id'])
  
          def raise_manila_exception(*args, **kwargs):
              raise exception.ManilaException()
  
          self.mock_object(db,
                           'share_server_get_all_by_host_and_share_subnet_valid',
                           mock.Mock(side_effect=raise_share_server_not_found))
          self.mock_object(self.share_manager, '_setup_server',
                           mock.Mock(side_effect=raise_manila_exception))
  
          self.assertRaises(
              exception.ManilaException,
              self.share_manager.create_share_instance,
              self.context,
              fake_share.instance['id'],
          )
          (db.share_server_get_all_by_host_and_share_subnet_valid.
              assert_called_once_with(
                  utils.IsAMatcher(context.RequestContext),
                  self.share_manager.host,
                  share_net_subnet['id'],
              ))
          db.share_server_create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), mock.ANY)
          db.share_instance_update.assert_has_calls([
              mock.call(
                  utils.IsAMatcher(context.RequestContext),
                  fake_share.instance['id'],
                  {'status': constants.STATUS_ERROR},
              )
          ])
          self.share_manager._setup_server.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_server,
              fake_metadata)
          manager.LOG.warning.assert_called_with(mock.ANY,
                                                 fake_share.instance['id'])
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.CREATE,
              six.text_type(fake_share.project_id),
              resource_type=message_field.Resource.SHARE,
              resource_id=fake_share['id'],
              detail=message_field.Detail.NO_SHARE_SERVER)
  
      def test_create_share_instance_with_share_network_subnet_not_found(self):
          """Test creation fails if share network not found."""
  
          self.mock_object(manager.LOG, 'warning')
  
          share = db_utils.create_share(share_network_id='fake-net-id')
          share_id = share['id']
          self.assertRaises(
              exception.ShareNetworkSubnetNotFound,
              self.share_manager.create_share_instance,
              self.context,
              share.instance['id']
          )
          manager.LOG.warning.assert_called_with(mock.ANY, share.instance['id'])
          shr = db.share_get(self.context, share_id)
          self.assertEqual(constants.STATUS_ERROR, shr['status'])
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.CREATE,
              six.text_type(shr.project_id),
              resource_type=message_field.Resource.SHARE,
              resource_id=shr['id'],
              detail=message_field.Detail.NO_SHARE_SERVER)
  
      def test_create_share_instance_with_security_service_missing(self):
          """Test creation fails if security service association is missing."""
  
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = True
          self.share_manager.driver.\
              dhss_mandatory_security_service_association = {
                  'fake_proto': ['fake_ss', 'fake_ss2', ]
              }
          ss_data = {
              'name': 'fake_name',
              'ou': 'fake_ou',
              'domain': 'fake_domain',
              'server': 'fake_server',
              'dns_ip': 'fake_dns_ip',
              'user': 'fake_user',
              'type': 'fake_ss',
              'password': 'fake_pass',
          }
          security_service = db_utils.create_security_service(**ss_data)
          share_net = db_utils.create_share_network()
          share_net_subnet = db_utils.create_share_network_subnet(
              share_network_id=share_net['id'],
              availability_zone_id=None,
          )
          db.share_network_add_security_service(context.get_admin_context(),
                                                share_net['id'],
                                                security_service['id'])
          share = db_utils.create_share(
              share_network_id=share_net['id'],
              share_proto='fake_proto',
          )
          db_utils.create_share_server(
              share_network_subnet_id=share_net_subnet['id'],
              host=self.share_manager.host,
              status=constants.STATUS_ERROR)
          fake_server = {
              'id': 'fake_srv_id',
              'status': constants.STATUS_CREATING,
          }
          fake_metadata = {
              'request_host': 'fake_host',
              'share_type_id': 'fake_share_type_id',
          }
          self.mock_object(self.share_manager, '_build_server_metadata',
                           mock.Mock(return_value=fake_metadata))
          self.mock_object(db, 'share_server_create',
                           mock.Mock(return_value=fake_server))
          self.mock_object(self.share_manager, '_setup_server',
                           mock.Mock(return_value=fake_server))
          self.assertRaises(
              exception.InvalidRequest,
              self.share_manager.create_share_instance,
              self.context,
              share.instance['id']
          )
          share = db.share_get(self.context, share['id'])
          self.assertEqual(constants.STATUS_ERROR, share['status'])
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.CREATE,
              str(share.project_id),
              resource_type=message_field.Resource.SHARE,
              resource_id=share['id'],
              detail=message_field.Detail.MISSING_SECURITY_SERVICE)
  
      @ddt.data(
          (True, 1, 3, 10, 0),
          (False, 1, 100, 5, 0),
          (True, 1, 3, 3, 0),
          (False, 1, 10, 10, 3),
          (False, 1, -1, 100, 3),
          (False, 1, 10, -1, 3),
      )
      @ddt.unpack
      def test__check_share_server_backend_limits(
              self, with_share_instance, resource_size, max_shares,
              max_gigabytes, expected_share_servers_len):
          share_servers = [db_utils.create_share_server() for i in range(3)]
          share = db_utils.create_share()
          share_instances = [
              db_utils.create_share_instance(
                  size=resource_size, share_id=share['id'])
              for i in range(3)]
          snapshot_instances = [
              db_utils.create_snapshot(
                  size=resource_size, share_id=share['id'])['instance']
              for i in range(3)]
  
          kwargs = {}
  
          driver_mock = mock.Mock()
          driver_mock.max_shares_per_share_server = max_shares
          driver_mock.max_share_server_size = max_gigabytes
          self.share_manager.driver = driver_mock
          self.mock_object(
              db, 'share_instances_get_all_by_share_server',
              mock.Mock(return_value=share_instances))
          self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(return_value=snapshot_instances))
  
          if with_share_instance:
              share_instance = db_utils.create_share_instance(
                  size=resource_size, share_id=share['id'])
              kwargs['share_instance'] = share_instance
  
          available_share_servers = (
              self.share_manager._check_share_server_backend_limits(
                  self.context, share_servers, **kwargs))
  
          self.assertEqual(
              expected_share_servers_len, len(available_share_servers))
  
      def test__check_share_server_backend_limits_unlimited(self):
          driver_mock = mock.Mock()
          driver_mock.max_shares_per_share_server = -1
          driver_mock.max_share_server_size = -1
          self.share_manager.driver = driver_mock
  
          share_servers = [db_utils.create_share_server() for i in range(3)]
  
          available_share_servers = (
              self.share_manager._check_share_server_backend_limits(
                  self.context, share_servers))
  
          self.assertEqual(share_servers, available_share_servers)
  
      def test_create_share_instance_with_share_network_server_exists(self):
          """Test share can be created with existing share server."""
          share_net = db_utils.create_share_network()
          share_net_subnet = db_utils.create_share_network_subnet(
              share_network_id=share_net['id'],
              availability_zone_id=None,
          )
          share = db_utils.create_share(share_network_id=share_net['id'])
          share_srv = db_utils.create_share_server(
              share_network_subnet_id=share_net_subnet['id'],
              host=self.share_manager.host)
  
          share_id = share['id']
  
          self.mock_object(manager.LOG, 'info')
          driver_mock = mock.Mock()
          driver_mock.max_shares_per_share_server = -1
          driver_mock.max_share_server_size = -1
          driver_mock.create_share.return_value = "fake_location"
          driver_mock.choose_share_server_compatible_with_share.return_value = (
              share_srv
          )
          self.share_manager.driver = driver_mock
          self.share_manager.driver.\
              dhss_mandatory_security_service_association = {}
          self.share_manager.create_share_instance(self.context,
                                                   share.instance['id'])
          self.assertFalse(self.share_manager.driver.setup_network.called)
          self.assertEqual(share_id, db.share_get(context.get_admin_context(),
                           share_id).id)
  
          shr = db.share_get(self.context, share_id)
          self.assertEqual(shr['status'], constants.STATUS_AVAILABLE)
          self.assertEqual(shr['share_server_id'], share_srv['id'])
          self.assertGreater(len(shr['export_location']), 0)
          self.assertEqual(1, len(shr['export_locations']))
          manager.LOG.info.assert_called_with(mock.ANY, share.instance['id'])
  
      @ddt.data('export_location', 'export_locations')
      def test_create_share_instance_with_error_in_driver(self, details_key):
          """Test db updates if share creation fails in driver."""
          share = db_utils.create_share()
          share_id = share['id']
          some_data = 'fake_location'
          self.share_manager.driver = mock.Mock()
          e = exception.ManilaException(detail_data={details_key: some_data})
          self.share_manager.driver.create_share.side_effect = e
          self.assertRaises(
              exception.ManilaException,
              self.share_manager.create_share_instance,
              self.context,
              share.instance['id']
          )
          self.assertTrue(self.share_manager.driver.create_share.called)
          shr = db.share_get(self.context, share_id)
          self.assertEqual(some_data, shr['export_location'])
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.CREATE,
              six.text_type(share.project_id),
              resource_type=message_field.Resource.SHARE,
              resource_id=share['id'],
              exception=mock.ANY)
  
      def test_create_share_instance_with_server_created(self):
          """Test share can be created and share server is created."""
          share_net = db_utils.create_share_network()
          share_net_subnet = db_utils.create_share_network_subnet(
              share_network_id=share_net['id'],
              availability_zone_id=None)
          share = db_utils.create_share(share_network_id=share_net['id'],
                                        availability_zone=None)
          db_utils.create_share_server(
              share_network_subnet_id=share_net_subnet['id'],
              host=self.share_manager.host,
              status=constants.STATUS_ERROR)
          share_id = share['id']
          fake_server = {
              'id': 'fake_srv_id',
              'status': constants.STATUS_CREATING,
          }
          fake_metadata = {
              'request_host': 'fake_host',
              'share_type_id': 'fake_share_type_id',
          }
  
          self.mock_object(self.share_manager, '_build_server_metadata',
                           mock.Mock(return_value=fake_metadata))
          self.mock_object(db, 'share_server_create',
                           mock.Mock(return_value=fake_server))
          self.mock_object(self.share_manager, '_setup_server',
                           mock.Mock(return_value=fake_server))
  
          self.share_manager.create_share_instance(self.context,
                                                   share.instance['id'])
  
          self.assertEqual(share_id, db.share_get(context.get_admin_context(),
                           share_id).id)
          shr = db.share_get(self.context, share_id)
          self.assertEqual(constants.STATUS_AVAILABLE, shr['status'])
          self.assertEqual('fake_srv_id', shr['share_server_id'])
          db.share_server_create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), mock.ANY)
          self.share_manager._setup_server.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_server,
              fake_metadata)
  
      def test_create_share_instance_update_replica_state(self):
          share_net = db_utils.create_share_network()
          share_net_subnet = db_utils.create_share_network_subnet(
              share_network_id=share_net['id'],
              availability_zone_id=None
          )
          share = db_utils.create_share(share_network_id=share_net['id'],
                                        replication_type='dr',
                                        availability_zone=None)
          db_utils.create_share_server(
              share_network_subnet_id=share_net_subnet['id'],
              host=self.share_manager.host, status=constants.STATUS_ERROR)
          share_id = share['id']
          fake_server = {
              'id': 'fake_srv_id',
              'status': constants.STATUS_CREATING,
          }
          fake_metadata = {
              'request_host': 'fake_host',
              'share_type_id': 'fake_share_type_id',
          }
          self.mock_object(self.share_manager, '_build_server_metadata',
                           mock.Mock(return_value=fake_metadata))
          self.mock_object(db, 'share_server_create',
                           mock.Mock(return_value=fake_server))
          self.mock_object(self.share_manager, '_setup_server',
                           mock.Mock(return_value=fake_server))
  
          self.share_manager.create_share_instance(self.context,
                                                   share.instance['id'])
  
          self.assertEqual(share_id, db.share_get(context.get_admin_context(),
                           share_id).id)
          shr = db.share_get(self.context, share_id)
          shr_instances = db.share_instances_get_all_by_share(
              self.context, shr['id'])
          self.assertEqual(1, len(shr_instances))
          self.assertEqual(constants.STATUS_AVAILABLE, shr['status'])
          self.assertEqual(
              constants.REPLICA_STATE_ACTIVE, shr_instances[0]['replica_state'])
          self.assertEqual('fake_srv_id', shr['share_server_id'])
          db.share_server_create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), mock.ANY)
          self.share_manager._setup_server.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_server,
              fake_metadata)
  
      @mock.patch('manila.tests.fake_notifier.FakeNotifier._notify')
      def test_create_delete_share_instance(self, mock_notify):
          """Test share can be created and deleted."""
          share = db_utils.create_share()
  
          mock_notify.assert_not_called()
  
          self.share_manager.create_share_instance(
              self.context, share.instance['id'])
  
          self.assert_notify_called(mock_notify,
                                    (['INFO', 'share.create.start'],
                                     ['INFO', 'share.create.end']))
  
          self.share_manager.delete_share_instance(
              self.context, share.instance['id'])
  
          self.assert_notify_called(mock_notify,
                                    (['INFO', 'share.create.start'],
                                     ['INFO', 'share.create.end'],
                                     ['INFO', 'share.delete.start'],
                                     ['INFO', 'share.delete.end']))
  
      @ddt.data(True, False)
      def test_create_delete_share_instance_error(self, exception_update_access):
          """Test share can be created and deleted with error."""
  
          def _raise_exception(self, *args, **kwargs):
              raise exception.ManilaException('fake')
  
          self.mock_object(self.share_manager.driver, "create_share",
                           mock.Mock(side_effect=_raise_exception))
          self.mock_object(self.share_manager.driver, "delete_share",
                           mock.Mock(side_effect=_raise_exception))
          if exception_update_access:
              self.mock_object(
                  self.share_manager.access_helper, "update_access_rules",
                  mock.Mock(side_effect=_raise_exception))
  
          share = db_utils.create_share()
          share_id = share['id']
          self.assertRaises(exception.ManilaException,
                            self.share_manager.create_share_instance,
                            self.context,
                            share.instance['id'])
  
          shr = db.share_get(self.context, share_id)
          self.assertEqual(constants.STATUS_ERROR, shr['status'])
          self.assertRaises(exception.ManilaException,
                            self.share_manager.delete_share_instance,
                            self.context,
                            share.instance['id'])
  
          shr = db.share_get(self.context, share_id)
          self.assertEqual(constants.STATUS_ERROR_DELETING, shr['status'])
          self.share_manager.driver.create_share.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              utils.IsAMatcher(models.ShareInstance),
              share_server=None)
          if not exception_update_access:
              self.share_manager.driver.delete_share.assert_called_once_with(
                  utils.IsAMatcher(context.RequestContext),
                  utils.IsAMatcher(models.ShareInstance),
                  share_server=None)
  
      def test_create_share_instance_update_availability_zone(self):
          share = db_utils.create_share(availability_zone=None)
          share_id = share['id']
  
          self.share_manager.create_share_instance(
              self.context, share.instance['id'])
  
          actual_share = db.share_get(context.get_admin_context(), share_id)
          self.assertIsNotNone(actual_share.availability_zone)
          self.assertEqual(manager.CONF.storage_availability_zone,
                           actual_share.availability_zone)
  
      def test_provide_share_server_for_share_incompatible_servers(self):
          fake_exception = exception.ManilaException("fake")
          fake_share_network = db_utils.create_share_network(id='fake_sn_id')
          fake_share_net_subnet = db_utils.create_share_network_subnet(
              id='fake_sns_id', share_network_id=fake_share_network['id']
          )
          fake_share_server = db_utils.create_share_server(id='fake')
          share = db_utils.create_share()
  
          db_method_mock = self.mock_object(
              db, 'share_network_subnet_get_by_availability_zone_id',
              mock.Mock(return_value=fake_share_net_subnet))
          self.mock_object(db,
                           'share_server_get_all_by_host_and_share_subnet_valid',
                           mock.Mock(return_value=[fake_share_server]))
          self.mock_object(
              self.share_manager, '_check_share_server_backend_limits',
              mock.Mock(return_value=[fake_share_server]))
          self.mock_object(
              self.share_manager.driver,
              "choose_share_server_compatible_with_share",
              mock.Mock(side_effect=fake_exception)
          )
  
          self.assertRaises(exception.ManilaException,
                            self.share_manager._provide_share_server_for_share,
                            self.context, fake_share_network['id'],
                            share.instance)
  
          db_method_mock.assert_called_once_with(
              self.context, fake_share_network['id'],
              availability_zone_id=share.instance.get('availability_zone_id')
          )
          driver_mock = self.share_manager.driver
          driver_method_mock = (
              driver_mock.choose_share_server_compatible_with_share
          )
          driver_method_mock.assert_called_once_with(
              self.context, [fake_share_server], share.instance,
              snapshot=None, share_group=None)
  
      def test_provide_share_server_for_share_invalid_arguments(self):
          self.assertRaises(ValueError,
                            self.share_manager._provide_share_server_for_share,
                            self.context, None, None)
  
      def test_provide_share_server_for_share_parent_ss_not_found(self):
          fake_parent_id = "fake_server_id"
          fake_share_network = db_utils.create_share_network(id='fake_sn_id')
          fake_exception = exception.ShareServerNotFound("fake")
          share = db_utils.create_share()
          fake_snapshot = {
              'share': {
                  'instance': {
                      'share_server_id': fake_parent_id
                  }
              }
          }
          self.mock_object(db, 'share_server_get',
                           mock.Mock(side_effect=fake_exception))
  
          self.assertRaises(exception.ShareServerNotFound,
                            self.share_manager._provide_share_server_for_share,
                            self.context, fake_share_network['id'],
                            share.instance, snapshot=fake_snapshot)
  
          db.share_server_get.assert_called_once_with(
              self.context, fake_parent_id)
  
      def test_provide_share_server_for_share_parent_ss_invalid(self):
          fake_parent_id = "fake_server_id"
          fake_share_network = db_utils.create_share_network(id='fake_sn_id')
          share = db_utils.create_share()
          fake_snapshot = {
              'share': {
                  'instance': {
                      'share_server_id': fake_parent_id
                  }
              }
          }
          fake_parent_share_server = {'status': 'fake'}
          self.mock_object(db, 'share_server_get',
                           mock.Mock(return_value=fake_parent_share_server))
  
          self.assertRaises(exception.InvalidShareServer,
                            self.share_manager._provide_share_server_for_share,
                            self.context, fake_share_network['id'],
                            share.instance, snapshot=fake_snapshot)
  
          db.share_server_get.assert_called_once_with(
              self.context, fake_parent_id)
  
      def test_provide_share_server_for_share_group_incompatible_servers(self):
          fake_exception = exception.ManilaException("fake")
          fake_share_server = {'id': 'fake'}
          sg = db_utils.create_share_group()
  
          self.mock_object(db,
                           'share_server_get_all_by_host_and_share_subnet_valid',
                           mock.Mock(return_value=[fake_share_server]))
          self.mock_object(
              self.share_manager.driver,
              "choose_share_server_compatible_with_share_group",
              mock.Mock(side_effect=fake_exception)
          )
  
          self.assertRaises(
              exception.ManilaException,
              self.share_manager._provide_share_server_for_share_group,
              self.context, "fake_sn_id", "fake_sns_id", sg)
  
          driver_mock = self.share_manager.driver
          driver_method_mock = (
              driver_mock.choose_share_server_compatible_with_share_group)
          driver_method_mock.assert_called_once_with(
              self.context, [fake_share_server], sg, share_group_snapshot=None)
  
      def test_provide_share_server_for_share_group_invalid_arguments(self):
          self.assertRaises(
              exception.InvalidInput,
              self.share_manager._provide_share_server_for_share_group,
              self.context, None, None, None)
  
      def test_manage_share_driver_exception(self):
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = False
          CustomException = type('CustomException', (Exception,), dict())
          self.mock_object(self.share_manager.driver,
                           'manage_existing',
                           mock.Mock(side_effect=CustomException))
          self.mock_object(share_types,
                           'get_share_type_extra_specs',
                           mock.Mock(return_value='False'))
          self.mock_object(
              self.share_manager, '_get_extra_specs_from_share_type',
              mock.Mock(return_value={}))
          self.mock_object(self.share_manager.db, 'share_update', mock.Mock())
          share = db_utils.create_share()
          share_id = share['id']
          driver_options = {'fake': 'fake'}
  
          self.assertRaises(
              CustomException,
              self.share_manager.manage_share,
              self.context, share_id, driver_options)
  
          (self.share_manager.driver.manage_existing.
              assert_called_once_with(mock.ANY, driver_options))
  
          self.share_manager.db.share_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), share_id,
              {'status': constants.STATUS_MANAGE_ERROR, 'size': 1})
          (self.share_manager._get_extra_specs_from_share_type.
              assert_called_once_with(
                  mock.ANY, share['instance']['share_type_id']))
  
      def _setup_provide_server_for_migration_test(self):
          source_share_server = db_utils.create_share_server()
          fake_share_network = db_utils.create_share_network()
          fake_network_subnet = db_utils.create_share_network_subnet(
              share_network_id=fake_share_network['id'])
          fake_dest_host = 'fakehost@fakebackend'
          fake_az = {
              'availability_zone_id': 'fake_az_id',
              'availability_zone_name': 'fake_az_name'
          }
          fake_data = {
              'source_share_server': source_share_server,
              'fake_share_network': fake_share_network,
              'fake_network_subnet': fake_network_subnet,
              'fake_dest_host': fake_dest_host,
              'fake_az': fake_az,
          }
          return fake_data
  
      def test__provide_share_server_for_migration_subnet_not_found(self):
          fake_data = self._setup_provide_server_for_migration_test()
  
          mock_subnet_get = self.mock_object(
              db, 'share_network_subnet_get_by_availability_zone_id',
              mock.Mock(return_value=None))
          self.assertRaises(
              exception.ShareNetworkSubnetNotFound,
              self.share_manager._provide_share_server_for_migration,
              self.context,
              fake_data['source_share_server'],
              fake_data['fake_share_network']['id'],
              fake_data['fake_az']['availability_zone_id'],
              fake_data['fake_dest_host']
          )
          mock_subnet_get.assert_called_once_with(
              self.context, fake_data['fake_share_network']['id'],
              availability_zone_id=fake_data['fake_az']['availability_zone_id'])
  
      def test__provide_share_server_for_migration(self):
          fake_data = self._setup_provide_server_for_migration_test()
          dest_share_server = db_utils.create_share_server()
          expected_share_server_data = {
              'host': self.share_manager.host,
              'share_network_subnet_id': fake_data['fake_network_subnet']['id'],
              'status': constants.STATUS_CREATING,
          }
          fake_metadata = {
              'migration_destination': True,
              'request_host': fake_data['fake_dest_host']
          }
  
          mock_subnet_get = self.mock_object(
              db, 'share_network_subnet_get_by_availability_zone_id',
              mock.Mock(return_value=fake_data['fake_network_subnet']))
          mock_server_create = self.mock_object(
              db, 'share_server_create',
              mock.Mock(return_value=dest_share_server))
          mock_create_server_in_backend = self.mock_object(
              self.share_manager, '_create_share_server_in_backend',
              mock.Mock(return_value=dest_share_server))
  
          result = self.share_manager._provide_share_server_for_migration(
              self.context,
              fake_data['source_share_server'],
              fake_data['fake_share_network']['id'],
              fake_data['fake_az']['availability_zone_id'],
              fake_data['fake_dest_host']
          )
          self.assertEqual(result, dest_share_server)
          mock_subnet_get.assert_called_once_with(
              self.context, fake_data['fake_share_network']['id'],
              availability_zone_id=fake_data['fake_az']['availability_zone_id'])
          mock_server_create.assert_called_once_with(
              self.context, expected_share_server_data)
          mock_create_server_in_backend.assert_called_once_with(
              self.context, dest_share_server, metadata=fake_metadata)
  
      def test_manage_share_invalid_size(self):
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = False
          self.mock_object(share_types,
                           'get_share_type_extra_specs',
                           mock.Mock(return_value='False'))
          self.mock_object(self.share_manager.driver,
                           "manage_existing",
                           mock.Mock(return_value=None))
          self.mock_object(self.share_manager.db, 'share_update', mock.Mock())
          self.mock_object(
              self.share_manager, '_get_extra_specs_from_share_type',
              mock.Mock(return_value={}))
          share = db_utils.create_share()
          share_id = share['id']
          driver_options = {'fake': 'fake'}
  
          self.assertRaises(
              exception.InvalidShare,
              self.share_manager.manage_share,
              self.context, share_id, driver_options)
  
          (self.share_manager.driver.manage_existing.
              assert_called_once_with(mock.ANY, driver_options))
          self.share_manager.db.share_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), share_id,
              {'status': constants.STATUS_MANAGE_ERROR, 'size': 1})
          (self.share_manager._get_extra_specs_from_share_type.
              assert_called_once_with(
                  mock.ANY, share['instance']['share_type_id']))
  
      def test_manage_share_quota_error(self):
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = False
          self.mock_object(share_types,
                           'get_share_type_extra_specs',
                           mock.Mock(return_value='False'))
          self.mock_object(self.share_manager.driver,
                           "manage_existing",
                           mock.Mock(return_value={'size': 3}))
          self.mock_object(quota.QUOTAS, 'reserve',
                           mock.Mock(side_effect=exception.QuotaError))
          self.mock_object(self.share_manager.db, 'share_update', mock.Mock())
          self.mock_object(
              self.share_manager, '_get_extra_specs_from_share_type',
              mock.Mock(return_value={}))
          share = db_utils.create_share()
          share_id = share['id']
          driver_options = {'fake': 'fake'}
  
          self.assertRaises(
              exception.QuotaError,
              self.share_manager.manage_share,
              self.context, share_id, driver_options)
  
          (self.share_manager.driver.manage_existing.
              assert_called_once_with(mock.ANY, driver_options))
          self.share_manager.db.share_update.assert_called_once_with(
              mock.ANY, share_id,
              {'status': constants.STATUS_MANAGE_ERROR, 'size': 1})
          (self.share_manager._get_extra_specs_from_share_type.
              assert_called_once_with(
                  mock.ANY, share['instance']['share_type_id']))
  
      def test_manage_share_incompatible_dhss(self):
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = False
          share = db_utils.create_share()
          self.mock_object(share_types,
                           'get_share_type_extra_specs',
                           mock.Mock(return_value="True"))
          self.mock_object(
              self.share_manager, '_get_extra_specs_from_share_type',
              mock.Mock(return_value={}))
          self.assertRaises(
              exception.InvalidShare, self.share_manager.manage_share,
              self.context, share['id'], {})
          (self.share_manager._get_extra_specs_from_share_type.
              assert_called_once_with(
                  mock.ANY, share['instance']['share_type_id']))
  
      @ddt.data({'dhss': True,
                 'driver_data': {'size': 1, 'replication_type': None}},
                {'dhss': False,
                 'driver_data': {'size': 2, 'name': 'fake',
                                 'replication_type': 'dr'}},
                {'dhss': False,
                 'driver_data': {'size': 3,
                                 'export_locations': ['foo', 'bar', 'quuz'],
                                 'replication_type': 'writable'}})
      @ddt.unpack
      def test_manage_share_valid_share(self, dhss, driver_data):
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = dhss
          replication_type = driver_data.pop('replication_type')
          extra_specs = {}
          if replication_type is not None:
              extra_specs.update({'replication_type': replication_type})
          export_locations = driver_data.get('export_locations')
          self.mock_object(self.share_manager.db, 'share_update', mock.Mock())
          self.mock_object(quota.QUOTAS, 'reserve', mock.Mock())
          self.mock_object(
              self.share_manager.db,
              'share_export_locations_update',
              mock.Mock(side_effect=(
                  self.share_manager.db.share_export_locations_update)))
          self.mock_object(share_types,
                           'get_share_type_extra_specs',
                           mock.Mock(return_value=six.text_type(dhss)))
          self.mock_object(
              self.share_manager, '_get_extra_specs_from_share_type',
              mock.Mock(return_value=extra_specs))
  
          if dhss:
              mock_manage = self.mock_object(
                  self.share_manager.driver,
                  "manage_existing_with_server",
                  mock.Mock(return_value=driver_data))
          else:
              mock_manage = self.mock_object(
                  self.share_manager.driver,
                  "manage_existing",
                  mock.Mock(return_value=driver_data))
          share = db_utils.create_share(replication_type=replication_type)
          share_id = share['id']
          driver_options = {'fake': 'fake'}
          expected_deltas = {
              'project_id': share['project_id'],
              'user_id': self.context.user_id,
              'shares': 1,
              'gigabytes': driver_data['size'],
              'share_type_id': share['instance']['share_type_id'],
              'overquota_allowed': True
          }
          if replication_type:
              expected_deltas.update({'share_replicas': 1,
                                      'replica_gigabytes': driver_data['size']})
  
          self.share_manager.manage_share(self.context, share_id, driver_options)
  
          if dhss:
              mock_manage.assert_called_once_with(mock.ANY, driver_options, None)
          else:
              mock_manage.assert_called_once_with(mock.ANY, driver_options)
          if export_locations:
              (self.share_manager.db.share_export_locations_update.
                  assert_called_once_with(
                      utils.IsAMatcher(context.RequestContext),
                      share.instance['id'], export_locations, delete=True))
          else:
              self.assertFalse(
                  self.share_manager.db.share_export_locations_update.called)
          valid_share_data = {
              'status': constants.STATUS_AVAILABLE, 'launched_at': mock.ANY}
          if replication_type:
              valid_share_data['replica_state'] = constants.REPLICA_STATE_ACTIVE
          valid_share_data.update(driver_data)
          self.share_manager.db.share_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              share_id, valid_share_data)
          quota.QUOTAS.reserve.assert_called_once_with(
              mock.ANY, **expected_deltas)
          (self.share_manager._get_extra_specs_from_share_type.
              assert_called_once_with(
                  mock.ANY, share['instance']['share_type_id']))
  
      def test_update_quota_usages_new(self):
          self.mock_object(self.share_manager.db, 'quota_usage_get',
                           mock.Mock(return_value={'in_use': 1}))
          self.mock_object(self.share_manager.db, 'quota_usage_update')
          project_id = 'fake_project_id'
          resource_name = 'fake'
          usage = 1
  
          self.share_manager._update_quota_usages(
              self.context, project_id, {resource_name: usage})
  
          self.share_manager.db.quota_usage_get.assert_called_once_with(
              mock.ANY, project_id, resource_name, mock.ANY)
          self.share_manager.db.quota_usage_update.assert_called_once_with(
              mock.ANY, project_id, mock.ANY, resource_name, in_use=2)
  
      def test_update_quota_usages_update(self):
          project_id = 'fake_project_id'
          resource_name = 'fake'
          usage = 1
          side_effect = exception.QuotaUsageNotFound(project_id=project_id)
          self.mock_object(
              self.share_manager.db,
              'quota_usage_get',
              mock.Mock(side_effect=side_effect))
          self.mock_object(self.share_manager.db, 'quota_usage_create')
  
          self.share_manager._update_quota_usages(
              self.context, project_id, {resource_name: usage})
  
          self.share_manager.db.quota_usage_get.assert_called_once_with(
              mock.ANY, project_id, resource_name, mock.ANY)
          self.share_manager.db.quota_usage_create.assert_called_once_with(
              mock.ANY, project_id, mock.ANY, resource_name, usage)
  
      def _setup_unmanage_mocks(self, mock_driver=True, mock_unmanage=None,
                                dhss=False, supports_replication=False):
          if mock_driver:
              self.mock_object(self.share_manager, 'driver')
          replicas_list = []
          if supports_replication:
              replicas_list.append({'id': 'fake_id'})
  
          if mock_unmanage:
              if dhss:
                  self.mock_object(
                      self.share_manager.driver, "unmanage_with_share_server",
                      mock_unmanage)
              else:
                  self.mock_object(self.share_manager.driver, "unmanage",
                                   mock_unmanage)
  
          self.mock_object(self.share_manager.db, 'share_update')
          self.mock_object(self.share_manager.db, 'share_instance_delete')
          self.mock_object(
              self.share_manager.db, 'share_replicas_get_all_by_share',
              mock.Mock(return_value=replicas_list))
  
      def test_unmanage_share_invalid_share(self):
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = False
          unmanage = mock.Mock(side_effect=exception.InvalidShare(reason="fake"))
          self._setup_unmanage_mocks(mock_driver=False, mock_unmanage=unmanage)
          share = db_utils.create_share()
  
          self.share_manager.unmanage_share(self.context, share['id'])
  
          self.share_manager.db.share_update.assert_called_once_with(
              mock.ANY, share['id'], {'status': constants.STATUS_UNMANAGE_ERROR})
          (self.share_manager.db.share_replicas_get_all_by_share.
              assert_called_once_with(mock.ANY, share['id']))
  
      @ddt.data(True, False)
      def test_unmanage_share_valid_share(self, supports_replication):
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = False
          self._setup_unmanage_mocks(
              mock_driver=False, mock_unmanage=mock.Mock(),
              supports_replication=supports_replication)
          self.mock_object(quota.QUOTAS, 'reserve')
          share = db_utils.create_share()
          share_id = share['id']
          share_instance_id = share.instance['id']
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(return_value=share.instance))
          reservation_params = {
              'project_id': share['project_id'],
              'shares': -1,
              'gigabytes': -share['size'],
              'share_type_id': share['instance']['share_type_id'],
          }
          if supports_replication:
              reservation_params.update(
                  {'share_replicas': -1, 'replica_gigabytes': -share['size']})
  
          self.share_manager.unmanage_share(self.context, share_id)
  
          (self.share_manager.driver.unmanage.
              assert_called_once_with(share.instance))
          self.share_manager.db.share_instance_delete.assert_called_once_with(
              mock.ANY, share_instance_id)
          quota.QUOTAS.reserve.assert_called_once_with(
              mock.ANY, **reservation_params)
          (self.share_manager.db.share_replicas_get_all_by_share.
              assert_called_once_with(mock.ANY, share['id']))
  
      @ddt.data(True, False)
      def test_unmanage_share_valid_share_with_share_server(
              self, supports_replication):
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = True
          self._setup_unmanage_mocks(
              mock_driver=False, mock_unmanage=mock.Mock(), dhss=True,
              supports_replication=supports_replication)
          server = db_utils.create_share_server(id='fake_server_id')
          share = db_utils.create_share(share_server_id='fake_server_id')
          self.mock_object(self.share_manager.db, 'share_server_update')
          self.mock_object(self.share_manager.db, 'share_server_get',
                           mock.Mock(return_value=server))
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(return_value=share.instance))
          self.mock_object(quota.QUOTAS, 'reserve')
          reservation_params = {
              'project_id': share['project_id'],
              'shares': -1,
              'gigabytes': -share['size'],
              'share_type_id': share['instance']['share_type_id'],
          }
          if supports_replication:
              reservation_params.update(
                  {'share_replicas': -1, 'replica_gigabytes': -share['size']})
  
          share_id = share['id']
          share_instance_id = share.instance['id']
  
          self.share_manager.unmanage_share(self.context, share_id)
  
          (self.share_manager.driver.unmanage_with_server.
              assert_called_once_with(share.instance, server))
          self.share_manager.db.share_instance_delete.assert_called_once_with(
              mock.ANY, share_instance_id)
          self.share_manager.db.share_server_update.assert_called_once_with(
              mock.ANY, server['id'], {'is_auto_deletable': False})
          quota.QUOTAS.reserve.assert_called_once_with(
              mock.ANY, **reservation_params)
          (self.share_manager.db.share_replicas_get_all_by_share
           .assert_called_once_with(mock.ANY, share['id']))
  
      def test_unmanage_share_valid_share_with_quota_error(self):
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = False
          self._setup_unmanage_mocks(mock_driver=False,
                                     mock_unmanage=mock.Mock())
          self.mock_object(quota.QUOTAS, 'reserve',
                           mock.Mock(side_effect=Exception()))
          share = db_utils.create_share()
          share_instance_id = share.instance['id']
  
          self.share_manager.unmanage_share(self.context, share['id'])
  
          self.share_manager.driver.unmanage.assert_called_once_with(mock.ANY)
          self.share_manager.db.share_instance_delete.assert_called_once_with(
              mock.ANY, share_instance_id)
          (self.share_manager.db.share_replicas_get_all_by_share.
              assert_called_once_with(mock.ANY, share['id']))
  
      def test_unmanage_share_remove_access_rules_error(self):
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = False
          manager.CONF.unmanage_remove_access_rules = True
          self._setup_unmanage_mocks(mock_driver=False,
                                     mock_unmanage=mock.Mock())
          self.mock_object(
              self.share_manager.access_helper,
              'update_access_rules',
              mock.Mock(side_effect=Exception())
          )
          self.mock_object(quota.QUOTAS, 'reserve', mock.Mock(return_value=[]))
          share = db_utils.create_share()
  
          self.share_manager.unmanage_share(self.context, share['id'])
  
          self.share_manager.db.share_update.assert_called_once_with(
              mock.ANY, share['id'], {'status': constants.STATUS_UNMANAGE_ERROR})
          (self.share_manager.db.share_replicas_get_all_by_share.
              assert_called_once_with(mock.ANY, share['id']))
  
      def test_unmanage_share_valid_share_remove_access_rules(self):
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = False
          manager.CONF.unmanage_remove_access_rules = True
          self._setup_unmanage_mocks(mock_driver=False,
                                     mock_unmanage=mock.Mock())
          smanager = self.share_manager
          self.mock_object(smanager.access_helper, 'update_access_rules')
          self.mock_object(quota.QUOTAS, 'reserve', mock.Mock(return_value=[]))
          share = db_utils.create_share()
          share_id = share['id']
          share_instance_id = share.instance['id']
  
          smanager.unmanage_share(self.context, share_id)
  
          smanager.driver.unmanage.assert_called_once_with(mock.ANY)
          smanager.access_helper.update_access_rules.assert_called_once_with(
              mock.ANY, mock.ANY, delete_all_rules=True, share_server=None
          )
          smanager.db.share_instance_delete.assert_called_once_with(
              mock.ANY, share_instance_id)
          (self.share_manager.db.share_replicas_get_all_by_share.
              assert_called_once_with(mock.ANY, share['id']))
  
      def test_delete_share_instance_share_server_not_found(self):
          share_net = db_utils.create_share_network()
          share = db_utils.create_share(share_network_id=share_net['id'],
                                        share_server_id='fake-id')
  
          self.assertRaises(
              exception.ShareServerNotFound,
              self.share_manager.delete_share_instance,
              self.context,
              share.instance['id']
          )
  
      @ddt.data(True, False)
      def test_delete_share_instance_last_on_srv_with_sec_service(
              self, with_details):
          share_net = db_utils.create_share_network()
          sec_service = db_utils.create_security_service(
              share_network_id=share_net['id'])
          backend_details = dict(
              security_service_ldap=jsonutils.dumps(sec_service))
          if with_details:
              share_srv = db_utils.create_share_server(
                  share_network_id=share_net['id'],
                  host=self.share_manager.host,
                  backend_details=backend_details)
          else:
              share_srv = db_utils.create_share_server(
                  share_network_id=share_net['id'],
                  host=self.share_manager.host)
              db.share_server_backend_details_set(
                  context.get_admin_context(), share_srv['id'], backend_details)
          share = db_utils.create_share(share_network_id=share_net['id'],
                                        share_server_id=share_srv['id'])
          mock_access_helper_call = self.mock_object(
              self.share_manager.access_helper, 'update_access_rules')
          self.share_manager.driver = mock.Mock()
          manager.CONF.delete_share_server_with_last_share = True
  
          self.share_manager.delete_share_instance(self.context,
                                                   share.instance['id'])
  
          mock_access_helper_call.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), share.instance['id'],
              delete_all_rules=True, share_server=mock.ANY)
          self.share_manager.driver.teardown_server.assert_called_once_with(
              server_details=backend_details,
              security_services=[jsonutils.loads(
                  backend_details['security_service_ldap'])])
  
      @ddt.data({'force': True, 'side_effect': 'update_access'},
                {'force': True, 'side_effect': 'delete_share'},
                {'force': False, 'side_effect': None})
      @ddt.unpack
      def test_delete_share_instance_last_on_server(self, force, side_effect):
          share_net = db_utils.create_share_network()
          share_srv = db_utils.create_share_server(
              share_network_id=share_net['id'],
              host=self.share_manager.host
          )
          share = db_utils.create_share(share_network_id=share_net['id'],
                                        share_server_id=share_srv['id'])
          share_srv = db.share_server_get(self.context, share_srv['id'])
          mock_access_helper_call = self.mock_object(
              self.share_manager.access_helper, 'update_access_rules')
          self.share_manager.driver = mock.Mock()
          if side_effect == 'update_access':
              mock_access_helper_call.side_effect = exception.ManilaException
          if side_effect == 'delete_share':
              self.mock_object(self.share_manager.driver, 'delete_share',
                               mock.Mock(side_effect=Exception('fake')))
          self.mock_object(manager.LOG, 'error')
          manager.CONF.delete_share_server_with_last_share = True
  
          self.share_manager.delete_share_instance(
              self.context, share.instance['id'], force=force)
  
          mock_access_helper_call.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), share.instance['id'],
              delete_all_rules=True, share_server=mock.ANY)
          self.share_manager.driver.teardown_server.assert_called_once_with(
              server_details=share_srv.get('backend_details'),
              security_services=[])
          self.assertEqual(force, manager.LOG.error.called)
  
      def test_delete_share_instance_last_on_server_deletion_disabled(self):
          share_net = db_utils.create_share_network()
          share_srv = db_utils.create_share_server(
              share_network_id=share_net['id'],
              host=self.share_manager.host
          )
          share = db_utils.create_share(share_network_id=share_net['id'],
                                        share_server_id=share_srv['id'])
          share_srv = db.share_server_get(self.context, share_srv['id'])
  
          manager.CONF.delete_share_server_with_last_share = False
          self.share_manager.driver = mock.Mock()
          mock_access_helper_call = self.mock_object(
              self.share_manager.access_helper, 'update_access_rules')
          self.mock_object(db, 'share_server_get',
                           mock.Mock(return_value=share_srv))
  
          self.share_manager.delete_share_instance(self.context,
                                                   share.instance['id'])
  
          mock_access_helper_call.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), share.instance['id'],
              delete_all_rules=True, share_server=share_srv)
          self.assertFalse(self.share_manager.driver.teardown_network.called)
  
      def test_delete_share_instance_not_last_on_server(self):
          share_net = db_utils.create_share_network()
          share_srv = db_utils.create_share_server(
              share_network_id=share_net['id'],
              host=self.share_manager.host
          )
          share = db_utils.create_share(share_network_id=share_net['id'],
                                        share_server_id=share_srv['id'])
          db_utils.create_share(share_network_id=share_net['id'],
                                share_server_id=share_srv['id'])
          share_srv = db.share_server_get(self.context, share_srv['id'])
  
          manager.CONF.delete_share_server_with_last_share = True
          self.share_manager.driver = mock.Mock()
          self.mock_object(db, 'share_server_get',
                           mock.Mock(return_value=share_srv))
          mock_access_helper_call = self.mock_object(
              self.share_manager.access_helper, 'update_access_rules')
  
          self.share_manager.delete_share_instance(self.context,
                                                   share.instance['id'])
  
          mock_access_helper_call.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), share.instance['id'],
              delete_all_rules=True, share_server=share_srv)
          self.assertFalse(self.share_manager.driver.teardown_network.called)
  
      @ddt.data('update_access', 'delete_share')
      def test_delete_share_instance_not_found(self, side_effect):
          share_net = db_utils.create_share_network()
          share_srv = db_utils.create_share_server(
              share_network_id=share_net['id'],
              host=self.share_manager.host)
          share = db_utils.create_share(share_network_id=share_net['id'],
                                        share_server_id=share_srv['id'])
          access = db_utils.create_access(share_id=share['id'])
          db_utils.create_share(share_network_id=share_net['id'],
                                share_server_id=share_srv['id'])
          share_srv = db.share_server_get(self.context, share_srv['id'])
  
          manager.CONF.delete_share_server_with_last_share = False
  
          self.mock_object(db, 'share_server_get',
                           mock.Mock(return_value=share_srv))
          self.mock_object(db, 'share_instance_get',
                           mock.Mock(return_value=share.instance))
          self.mock_object(db, 'share_access_get_all_for_instance',
                           mock.Mock(return_value=[access]))
          self.share_manager.driver = mock.Mock()
          self.share_manager.access_helper.driver = mock.Mock()
          if side_effect == 'update_access':
              mock_access_helper_call = self.mock_object(
                  self.share_manager.access_helper, 'update_access_rules',
                  mock.Mock(side_effect=exception.ShareResourceNotFound(
                      share_id=share['id'])))
          if side_effect == 'delete_share':
              mock_access_helper_call = self.mock_object(
                  self.share_manager.access_helper, 'update_access_rules',
                  mock.Mock(return_value=None)
              )
              self.mock_object(
                  self.share_manager.driver, 'delete_share',
                  mock.Mock(side_effect=exception.ShareResourceNotFound(
                      share_id=share['id'])))
  
          self.mock_object(manager.LOG, 'warning')
  
          self.share_manager.delete_share_instance(self.context,
                                                   share.instance['id'])
          self.assertFalse(self.share_manager.driver.teardown_network.called)
  
          mock_access_helper_call.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), share.instance['id'],
              delete_all_rules=True, share_server=share_srv)
          self.assertTrue(manager.LOG.warning.called)
  
      def test_setup_server(self):
          # Setup required test data
          metadata = {'fake_metadata_key': 'fake_metadata_value'}
          share_network = db_utils.create_share_network(id='fake_sn_id')
          share_net_subnet = db_utils.create_share_network_subnet(
              id='fake_sns_id', share_network_id=share_network['id']
          )
          share_server = db_utils.create_share_server(
              id='fake_id', share_network_subnet_id=share_net_subnet['id'])
          network_info = {'security_services': []}
          for ss_type in constants.SECURITY_SERVICES_ALLOWED_TYPES:
              network_info['security_services'].append({
                  'name': 'fake_name' + ss_type,
                  'ou': 'fake_ou' + ss_type,
                  'domain': 'fake_domain' + ss_type,
                  'server': 'fake_server' + ss_type,
                  'dns_ip': 'fake_dns_ip' + ss_type,
                  'user': 'fake_user' + ss_type,
                  'type': ss_type,
                  'password': 'fake_password' + ss_type,
              })
          sec_services = network_info['security_services']
          server_info = {'fake_server_info_key': 'fake_server_info_value'}
          network_info['network_type'] = 'fake_network_type'
  
          # mock required stuff
          self.mock_object(self.share_manager.db, 'share_network_subnet_get',
                           mock.Mock(return_value=share_net_subnet))
          self.mock_object(self.share_manager.db, 'share_network_get',
                           mock.Mock(return_value=share_network))
          self.mock_object(self.share_manager.driver, 'allocate_network')
          self.mock_object(self.share_manager, '_form_server_setup_info',
                           mock.Mock(return_value=network_info))
          self.mock_object(self.share_manager, '_validate_segmentation_id')
          self.mock_object(self.share_manager.driver, 'setup_server',
                           mock.Mock(return_value=server_info))
          self.mock_object(self.share_manager.db,
                           'share_server_backend_details_set')
          self.mock_object(self.share_manager.db, 'share_server_update',
                           mock.Mock(return_value=share_server))
  
          # execute method _setup_server
          result = self.share_manager._setup_server(
              self.context, share_server, metadata)
  
          # verify results
          self.assertEqual(share_server, result)
          self.share_manager.db.share_network_get.assert_called_once_with(
              self.context, share_net_subnet['share_network_id'])
          self.share_manager.db.share_network_subnet_get.assert_called_once_with(
              self.context, share_server['share_network_subnet']['id'])
          self.share_manager.driver.allocate_network.assert_called_once_with(
              self.context, share_server, share_network,
              share_server['share_network_subnet'])
          self.share_manager._form_server_setup_info.assert_called_once_with(
              self.context, share_server, share_network, share_net_subnet)
          self.share_manager._validate_segmentation_id.assert_called_once_with(
              network_info)
          self.share_manager.driver.setup_server.assert_called_once_with(
              network_info, metadata=metadata)
          (self.share_manager.db.share_server_backend_details_set.
              assert_has_calls([
                  mock.call(self.context, share_server['id'],
                            {'security_service_' + sec_services[0]['type']:
                                jsonutils.dumps(sec_services[0])}),
                  mock.call(self.context, share_server['id'],
                            {'security_service_' + sec_services[1]['type']:
                                jsonutils.dumps(sec_services[1])}),
                  mock.call(self.context, share_server['id'],
                            {'security_service_' + sec_services[2]['type']:
                                jsonutils.dumps(sec_services[2])}),
                  mock.call(self.context, share_server['id'], server_info),
              ]))
          self.share_manager.db.share_server_update.assert_called_once_with(
              self.context, share_server['id'],
              {'status': constants.STATUS_ACTIVE,
               'identifier': share_server['id']})
  
      def test_setup_server_server_info_not_present(self):
          # Setup required test data
          metadata = {'fake_metadata_key': 'fake_metadata_value'}
          share_network = {'id': 'fake_sn_id'}
          share_net_subnet = {'id': 'fake_sns_id',
                              'share_network_id': share_network['id']}
          share_server = {
              'id': 'fake_id',
              'share_network_subnet': share_net_subnet,
          }
          network_info = {
              'fake_network_info_key': 'fake_network_info_value',
              'security_services': [],
              'network_type': 'fake_network_type',
          }
          server_info = {}
  
          # mock required stuff
          self.mock_object(self.share_manager.db, 'share_network_subnet_get',
                           mock.Mock(return_value=share_net_subnet))
          self.mock_object(self.share_manager.db, 'share_network_get',
                           mock.Mock(return_value=share_network))
          self.mock_object(self.share_manager, '_form_server_setup_info',
                           mock.Mock(return_value=network_info))
          self.mock_object(self.share_manager.driver, 'setup_server',
                           mock.Mock(return_value=server_info))
          self.mock_object(self.share_manager.db, 'share_server_update',
                           mock.Mock(return_value=share_server))
          self.mock_object(self.share_manager.driver, 'allocate_network')
  
          # execute method _setup_server
          result = self.share_manager._setup_server(
              self.context, share_server, metadata)
  
          # verify results
          self.assertEqual(share_server, result)
          self.share_manager.db.share_network_get.assert_called_once_with(
              self.context, share_net_subnet['share_network_id'])
          self.share_manager.db.share_network_subnet_get.assert_called_once_with(
              self.context, share_server['share_network_subnet']['id'])
          self.share_manager._form_server_setup_info.assert_called_once_with(
              self.context, share_server, share_network, share_net_subnet)
          self.share_manager.driver.setup_server.assert_called_once_with(
              network_info, metadata=metadata)
          self.share_manager.db.share_server_update.assert_called_once_with(
              self.context, share_server['id'],
              {'status': constants.STATUS_ACTIVE,
               'identifier': share_server['id']})
          self.share_manager.driver.allocate_network.assert_called_once_with(
              self.context, share_server, share_network, share_net_subnet)
  
      def setup_server_raise_exception(self, detail_data_proper):
          # Setup required test data
          metadata = {'fake_metadata_key': 'fake_metadata_value'}
          server_info = {'details_key': 'value'}
          share_network = {'id': 'fake_sn_id'}
          share_net_subnet = {'id': 'fake_sns_id',
                              'share_network_id': share_network['id']}
          share_server = {
              'id': 'fake_id',
              'share_network_subnet': share_net_subnet
          }
          network_info = {
              'fake_network_info_key': 'fake_network_info_value',
              'security_services': [],
              'network_type': 'fake_network_type',
          }
          if detail_data_proper:
              detail_data = {'server_details': server_info}
              self.mock_object(self.share_manager.db,
                               'share_server_backend_details_set')
          else:
              detail_data = 'not dictionary detail data'
  
          # Mock required parameters
          self.mock_object(self.share_manager.db, 'share_network_get',
                           mock.Mock(return_value=share_network))
          self.mock_object(self.share_manager.db, 'share_network_subnet_get',
                           mock.Mock(return_value=share_net_subnet))
          self.mock_object(self.share_manager.db, 'share_server_update')
          for m in ['deallocate_network', 'allocate_network']:
              self.mock_object(self.share_manager.driver, m)
          self.mock_object(self.share_manager, '_form_server_setup_info',
                           mock.Mock(return_value=network_info))
          self.mock_object(self.share_manager.db,
                           'share_server_backend_details_set')
          self.mock_object(self.share_manager.driver, 'setup_server',
                           mock.Mock(side_effect=exception.ManilaException(
                               detail_data=detail_data)))
  
          # execute method _setup_server
          self.assertRaises(
              exception.ManilaException,
              self.share_manager._setup_server,
              self.context,
              share_server,
              metadata,
          )
  
          # verify results
          if detail_data_proper:
              (self.share_manager.db.share_server_backend_details_set.
                  assert_called_once_with(
                      self.context, share_server['id'], server_info))
          self.share_manager._form_server_setup_info.assert_called_once_with(
              self.context, share_server, share_network, share_net_subnet)
          self.share_manager.db.share_server_update.assert_called_once_with(
              self.context, share_server['id'],
              {'status': constants.STATUS_ERROR})
          self.share_manager.db.share_network_get.assert_called_once_with(
              self.context, share_net_subnet['share_network_id'])
          self.share_manager.db.share_network_subnet_get.assert_called_once_with(
              self.context, share_server['share_network_subnet']['id'])
          self.share_manager.driver.allocate_network.assert_has_calls([
              mock.call(self.context, share_server, share_network,
                        share_net_subnet)])
          self.share_manager.driver.deallocate_network.assert_has_calls([
              mock.call(self.context, share_server['id'])])
  
      def test_setup_server_incorrect_detail_data(self):
          self.setup_server_raise_exception(detail_data_proper=False)
  
      def test_setup_server_exception_in_driver(self):
          self.setup_server_raise_exception(detail_data_proper=True)
  
      @ddt.data({},
                {'detail_data': 'fake'},
                {'detail_data': {'server_details': 'fake'}},
                {'detail_data': {'server_details': {'fake': 'fake'}}},
                {'detail_data': {
                    'server_details': {'fake': 'fake', 'fake2': 'fake2'}}},)
      def test_setup_server_exception_in_cleanup_after_error(self, data):
  
          def get_server_details_from_data(data):
              d = data.get('detail_data')
              if not isinstance(d, dict):
                  return {}
              d = d.get('server_details')
              if not isinstance(d, dict):
                  return {}
              return d
          share_net_subnet = db_utils.create_share_network_subnet(
              id='fake_subnet_id', share_network_id='fake_share_net_id'
          )
          share_server = db_utils.create_share_server(
              id='fake', share_network_subnet_id=share_net_subnet['id'])
          details = get_server_details_from_data(data)
          metadata = {'fake_metadata_key': 'fake_metadata_value'}
  
          exc_mock = mock.Mock(side_effect=exception.ManilaException(**data))
          details_mock = mock.Mock(side_effect=exception.ManilaException())
          self.mock_object(self.share_manager.db, 'share_network_get',
                           exc_mock)
          self.mock_object(self.share_manager.db,
                           'share_server_backend_details_set', details_mock)
          self.mock_object(self.share_manager.db, 'share_server_update')
          self.mock_object(self.share_manager.driver, 'deallocate_network')
          self.mock_object(manager.LOG, 'debug')
          self.mock_object(manager.LOG, 'warning')
  
          self.assertRaises(
              exception.ManilaException,
              self.share_manager._setup_server,
              self.context,
              share_server,
              metadata,
          )
  
          self.assertTrue(self.share_manager.db.share_network_get.called)
          if details:
              self.assertEqual(len(details), details_mock.call_count)
              expected = [mock.call(mock.ANY, share_server['id'], {k: v})
                          for k, v in details.items()]
              self.assertEqual(expected, details_mock.call_args_list)
          self.share_manager.db.share_server_update.assert_called_once_with(
              self.context,
              share_server['id'],
              {'status': constants.STATUS_ERROR})
          self.share_manager.driver.deallocate_network.assert_called_once_with(
              self.context, share_server['id']
          )
          self.assertFalse(manager.LOG.warning.called)
          if get_server_details_from_data(data):
              self.assertTrue(manager.LOG.debug.called)
  
      def test_ensure_share_instance_has_pool_with_only_host(self):
          fake_share = {
              'status': constants.STATUS_AVAILABLE, 'host': 'host1', 'id': 1}
          host = self.share_manager._ensure_share_instance_has_pool(
              context.get_admin_context(), fake_share)
          self.assertIsNone(host)
  
      def test_ensure_share_instance_has_pool_with_full_pool_name(self):
          fake_share = {'host': 'host1#pool0', 'id': 1,
                        'status': constants.STATUS_AVAILABLE}
          fake_share_expected_value = 'pool0'
          host = self.share_manager._ensure_share_instance_has_pool(
              context.get_admin_context(), fake_share)
          self.assertEqual(fake_share_expected_value, host)
  
      def test_ensure_share_instance_has_pool_unable_to_fetch_share(self):
          fake_share = {'host': 'host@backend', 'id': 1,
                        'status': constants.STATUS_AVAILABLE}
          with mock.patch.object(self.share_manager.driver, 'get_pool',
                                 side_effect=Exception):
              with mock.patch.object(manager, 'LOG') as mock_LOG:
                  self.share_manager._ensure_share_instance_has_pool(
                      context.get_admin_context(), fake_share)
                  self.assertEqual(1, mock_LOG.exception.call_count)
  
      def test_ensure_share_instance_pool_notexist_and_get_from_driver(self):
          fake_share_instance = {'host': 'host@backend', 'id': 1,
                                 'status': constants.STATUS_AVAILABLE}
          fake_host_expected_value = 'fake_pool'
          self.mock_object(self.share_manager.db, 'share_instance_update')
          self.mock_object(self.share_manager.driver, 'get_pool',
                           mock.Mock(return_value='fake_pool'))
  
          host = self.share_manager._ensure_share_instance_has_pool(
              context.get_admin_context(), fake_share_instance)
  
          self.share_manager.db.share_instance_update.assert_any_call(
              mock.ANY, 1, {'host': 'host@backend#fake_pool'})
          self.assertEqual(fake_host_expected_value, host)
  
      def test__form_server_setup_info(self):
          def fake_network_allocations_get_for_share_server(*args, **kwargs):
              if kwargs.get('label') != 'admin':
                  return ['foo', 'bar']
              return ['admin-foo', 'admin-bar']
  
          self.mock_object(
              self.share_manager.db, 'network_allocations_get_for_share_server',
              mock.Mock(
                  side_effect=fake_network_allocations_get_for_share_server))
          fake_share_server = dict(
              id='fake_share_server_id', backend_details=dict(foo='bar'))
          fake_share_network = dict(
              security_services='fake_security_services'
          )
          fake_share_network_subnet = dict(
              segmentation_id='fake_segmentation_id',
              cidr='fake_cidr',
              neutron_net_id='fake_neutron_net_id',
              neutron_subnet_id='fake_neutron_subnet_id',
              network_type='fake_network_type')
          expected = dict(
              server_id=fake_share_server['id'],
              segmentation_id=fake_share_network_subnet['segmentation_id'],
              cidr=fake_share_network_subnet['cidr'],
              neutron_net_id=fake_share_network_subnet['neutron_net_id'],
              neutron_subnet_id=fake_share_network_subnet['neutron_subnet_id'],
              security_services=fake_share_network['security_services'],
              network_allocations=(
                  fake_network_allocations_get_for_share_server()),
              admin_network_allocations=(
                  fake_network_allocations_get_for_share_server(label='admin')),
              backend_details=fake_share_server['backend_details'],
              network_type=fake_share_network_subnet['network_type'])
  
          network_info = self.share_manager._form_server_setup_info(
              self.context, fake_share_server, fake_share_network,
              fake_share_network_subnet)
  
          self.assertEqual(expected, network_info)
          (self.share_manager.db.network_allocations_get_for_share_server.
              assert_has_calls([
                  mock.call(self.context, fake_share_server['id'], label='user'),
                  mock.call(self.context, fake_share_server['id'], label='admin')
              ]))
  
      @ddt.data(
          {'network_info': {'network_type': 'vlan', 'segmentation_id': '100'}},
          {'network_info': {'network_type': 'vlan', 'segmentation_id': '1'}},
          {'network_info': {'network_type': 'vlan', 'segmentation_id': '4094'}},
          {'network_info': {'network_type': 'vxlan', 'segmentation_id': '100'}},
          {'network_info': {'network_type': 'vxlan', 'segmentation_id': '1'}},
          {'network_info': {'network_type': 'vxlan',
                            'segmentation_id': '16777215'}},
          {'network_info': {'network_type': 'gre', 'segmentation_id': '100'}},
          {'network_info': {'network_type': 'gre', 'segmentation_id': '1'}},
          {'network_info': {'network_type': 'gre',
                            'segmentation_id': '4294967295'}},
          {'network_info': {'network_type': 'flat', 'segmentation_id': None}},
          {'network_info': {'network_type': 'flat', 'segmentation_id': 0}},
          {'network_info': {'network_type': None, 'segmentation_id': None}},
          {'network_info': {'network_type': None, 'segmentation_id': 0}})
      @ddt.unpack
      def test_validate_segmentation_id_with_valid_values(self, network_info):
          self.share_manager._validate_segmentation_id(network_info)
  
      @ddt.data(
          {'network_info': {'network_type': 'vlan', 'segmentation_id': None}},
          {'network_info': {'network_type': 'vlan', 'segmentation_id': -1}},
          {'network_info': {'network_type': 'vlan', 'segmentation_id': 0}},
          {'network_info': {'network_type': 'vlan', 'segmentation_id': '4095'}},
          {'network_info': {'network_type': 'vxlan', 'segmentation_id': None}},
          {'network_info': {'network_type': 'vxlan', 'segmentation_id': 0}},
          {'network_info': {'network_type': 'vxlan',
                            'segmentation_id': '16777216'}},
          {'network_info': {'network_type': 'gre', 'segmentation_id': None}},
          {'network_info': {'network_type': 'gre', 'segmentation_id': 0}},
          {'network_info': {'network_type': 'gre',
                            'segmentation_id': '4294967296'}},
          {'network_info': {'network_type': 'flat', 'segmentation_id': '1000'}},
          {'network_info': {'network_type': None, 'segmentation_id': '1000'}})
      @ddt.unpack
      def test_validate_segmentation_id_with_invalid_values(self, network_info):
          self.assertRaises(exception.NetworkBadConfigurationException,
                            self.share_manager._validate_segmentation_id,
                            network_info)
  
      @ddt.data(10, 36, 60)
      def test_verify_server_cleanup_interval_valid_cases(self, val):
          data = dict(DEFAULT=dict(unused_share_server_cleanup_interval=val))
          with test_utils.create_temp_config_with_opts(data):
              manager.ShareManager()
  
      @mock.patch.object(db, 'share_server_get_all_unused_deletable',
                         mock.Mock())
      @mock.patch.object(manager.ShareManager, 'delete_share_server',
                         mock.Mock())
      def test_delete_free_share_servers_cleanup_disabled(self):
          data = dict(DEFAULT=dict(automatic_share_server_cleanup=False))
          with test_utils.create_temp_config_with_opts(data):
              share_manager = manager.ShareManager()
              share_manager.driver.initialized = True
              share_manager.delete_free_share_servers(self.context)
              self.assertFalse(db.share_server_get_all_unused_deletable.called)
  
      @mock.patch.object(db, 'share_server_get_all_unused_deletable',
                         mock.Mock())
      @mock.patch.object(manager.ShareManager, 'delete_share_server',
                         mock.Mock())
      def test_delete_free_share_servers_driver_handles_ss_disabled(self):
          data = dict(DEFAULT=dict(driver_handles_share_servers=False))
          with test_utils.create_temp_config_with_opts(data):
              share_manager = manager.ShareManager()
              share_manager.driver.initialized = True
              share_manager.delete_free_share_servers(self.context)
              self.assertFalse(db.share_server_get_all_unused_deletable.called)
              self.assertFalse(share_manager.delete_share_server.called)
  
      @mock.patch.object(db, 'share_server_get_all_unused_deletable',
                         mock.Mock(return_value=['server1', ]))
      @mock.patch.object(manager.ShareManager, 'delete_share_server',
                         mock.Mock())
      @mock.patch.object(timeutils, 'utcnow', mock.Mock(
                         return_value=datetime.timedelta(minutes=20)))
      def test_delete_free_share_servers(self):
          self.share_manager.delete_free_share_servers(self.context)
          db.share_server_get_all_unused_deletable.assert_called_once_with(
              self.context,
              self.share_manager.host,
              datetime.timedelta(minutes=10))
          self.share_manager.delete_share_server.assert_called_once_with(
              self.context,
              'server1')
          timeutils.utcnow.assert_called_once_with()
  
      @mock.patch('manila.tests.fake_notifier.FakeNotifier._notify')
      def test_extend_share_invalid(self, mock_notify):
          share = db_utils.create_share()
          share_id = share['id']
          reservations = {}
  
          mock_notify.assert_not_called()
  
          self.mock_object(self.share_manager, 'driver')
          self.mock_object(self.share_manager.db, 'share_update')
          self.mock_object(quota.QUOTAS, 'rollback')
          self.mock_object(self.share_manager.driver, 'extend_share',
                           mock.Mock(side_effect=Exception('fake')))
  
          self.assertRaises(
              exception.ShareExtendingError,
              self.share_manager.extend_share, self.context, share_id, 123, {})
  
          quota.QUOTAS.rollback.assert_called_once_with(
              mock.ANY,
              reservations,
              project_id=six.text_type(share['project_id']),
              user_id=six.text_type(share['user_id']),
              share_type_id=None,
          )
  
      @mock.patch('manila.tests.fake_notifier.FakeNotifier._notify')
      def test_extend_share(self, mock_notify):
          share = db_utils.create_share()
          share_id = share['id']
          new_size = 123
          shr_update = {
              'size': int(new_size),
              'status': constants.STATUS_AVAILABLE.lower()
          }
          reservations = {}
          fake_share_server = 'fake'
  
          mock_notify.assert_not_called()
  
          manager = self.share_manager
          self.mock_object(manager, 'driver')
          self.mock_object(manager.db, 'share_get',
                           mock.Mock(return_value=share))
          self.mock_object(manager.db, 'share_update',
                           mock.Mock(return_value=share))
          self.mock_object(quota.QUOTAS, 'commit')
          self.mock_object(manager.driver, 'extend_share')
          self.mock_object(manager, '_get_share_server',
                           mock.Mock(return_value=fake_share_server))
  
          self.share_manager.extend_share(self.context, share_id,
                                          new_size, reservations)
  
          self.assertTrue(manager._get_share_server.called)
          manager.driver.extend_share.assert_called_once_with(
              utils.IsAMatcher(models.ShareInstance),
              new_size, share_server=fake_share_server
          )
          quota.QUOTAS.commit.assert_called_once_with(
              mock.ANY, reservations, project_id=share['project_id'],
              user_id=share['user_id'], share_type_id=None)
          manager.db.share_update.assert_called_once_with(
              mock.ANY, share_id, shr_update
          )
  
          self.assert_notify_called(mock_notify,
                                    (['INFO', 'share.extend.start'],
                                     ['INFO', 'share.extend.end']))
  
      def test_shrink_share_not_supported(self):
          share = db_utils.create_share(size=2)
          new_size = 1
          share_id = share['id']
  
          self.mock_object(self.share_manager.db, 'share_get',
                           mock.Mock(return_value=share))
          self.mock_object(self.share_manager, 'driver')
          self.mock_object(self.share_manager.db, 'share_update')
  
          self.mock_object(quota.QUOTAS, 'reserve')
          self.mock_object(quota.QUOTAS, 'rollback')
          self.mock_object(self.share_manager.driver, 'shrink_share',
                           mock.Mock(side_effect=NotImplementedError))
  
          self.assertRaises(
              exception.ShareShrinkingError,
              self.share_manager.shrink_share, self.context, share_id, new_size)
  
          self.share_manager.driver.shrink_share.assert_called_once_with(
              utils.IsAMatcher(models.ShareInstance),
              new_size, share_server=None
          )
  
          self.share_manager.db.share_update.assert_called_once_with(
              mock.ANY, share_id, {'status': constants.STATUS_AVAILABLE}
          )
  
          quota.QUOTAS.reserve.assert_called_once_with(
              mock.ANY, gigabytes=-1, project_id=share['project_id'],
              share_type_id=None, user_id=share['user_id'],
          )
          quota.QUOTAS.rollback.assert_called_once_with(
              mock.ANY, mock.ANY, project_id=share['project_id'],
              share_type_id=None, user_id=share['user_id'],
          )
          self.assertTrue(self.share_manager.db.share_get.called)
  
          self.share_manager.message_api.create.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              message_field.Action.SHRINK,
              share['project_id'],
              resource_type=message_field.Resource.SHARE,
              resource_id=share_id,
              detail=message_field.Detail.DRIVER_FAILED_SHRINK)
  
      @ddt.data((True, [{'id': 'fake'}]), (False, []))
      @ddt.unpack
      def test_shrink_share_quota_error(self, supports_replication,
                                        replicas_list):
          size = 5
          new_size = 1
          share = db_utils.create_share(size=size)
          share_id = share['id']
  
          self.mock_object(self.share_manager.db, 'share_update')
          self.mock_object(quota.QUOTAS, 'reserve',
                           mock.Mock(side_effect=Exception('fake')))
          self.mock_object(
              self.share_manager.db, 'share_replicas_get_all_by_share',
              mock.Mock(return_value=replicas_list))
  
          deltas = {}
          if supports_replication:
              deltas.update({'replica_gigabytes': new_size - size})
  
          self.assertRaises(
              exception.ShareShrinkingError,
              self.share_manager.shrink_share, self.context, share_id, new_size)
  
          quota.QUOTAS.reserve.assert_called_with(
              mock.ANY,
              project_id=six.text_type(share['project_id']),
              user_id=six.text_type(share['user_id']),
              share_type_id=None,
              gigabytes=new_size - size,
              **deltas
          )
          self.assertTrue(self.share_manager.db.share_update.called)
          (self.share_manager.db.share_replicas_get_all_by_share
              .assert_called_once_with(mock.ANY, share['id']))
  
      @ddt.data({'exc': exception.InvalidShare("fake"),
                 'status': constants.STATUS_SHRINKING_ERROR},
                {'exc': exception.ShareShrinkingPossibleDataLoss("fake"),
                 'status': constants.STATUS_AVAILABLE})
      @ddt.unpack
      def test_shrink_share_invalid(self, exc, status):
          share = db_utils.create_share()
          new_size = 1
          share_id = share['id']
          size_decrease = int(share['size']) - new_size
  
          self.mock_object(self.share_manager, 'driver')
          self.mock_object(self.share_manager.db, 'share_update')
          self.mock_object(self.share_manager.db, 'share_get',
                           mock.Mock(return_value=share))
          self.mock_object(quota.QUOTAS, 'reserve')
          self.mock_object(quota.QUOTAS, 'rollback')
          self.mock_object(self.share_manager.driver, 'shrink_share',
                           mock.Mock(side_effect=exc))
  
          self.assertRaises(
              exception.ShareShrinkingError,
              self.share_manager.shrink_share, self.context, share_id, new_size)
  
          self.share_manager.driver.shrink_share.assert_called_once_with(
              utils.IsAMatcher(models.ShareInstance),
              new_size, share_server=None
          )
          self.share_manager.db.share_update.assert_called_once_with(
              mock.ANY, share_id, {'status': status}
          )
          quota.QUOTAS.reserve.assert_called_once_with(
              mock.ANY, gigabytes=-size_decrease, project_id=share['project_id'],
              share_type_id=None, user_id=share['user_id'],
          )
          quota.QUOTAS.rollback.assert_called_once_with(
              mock.ANY, mock.ANY, project_id=share['project_id'],
              share_type_id=None, user_id=share['user_id'],
          )
          self.assertTrue(self.share_manager.db.share_get.called)
  
          if isinstance(exc, exception.ShareShrinkingPossibleDataLoss):
              self.share_manager.message_api.create.assert_called_once_with(
                  utils.IsAMatcher(context.RequestContext),
                  message_field.Action.SHRINK,
                  share['project_id'],
                  resource_type=message_field.Resource.SHARE,
                  resource_id=share_id,
                  detail=message_field.Detail.DRIVER_REFUSED_SHRINK)
  
      @ddt.data(True, False)
      def test_shrink_share(self, supports_replication):
          share = db_utils.create_share()
          share_id = share['id']
          new_size = 123
          shr_update = {
              'size': int(new_size),
              'status': constants.STATUS_AVAILABLE
          }
          fake_share_server = 'fake'
          size_decrease = int(share['size']) - new_size
          mock_notify = self.mock_object(fake_notifier.FakeNotifier, '_notify')
          replicas_list = []
          if supports_replication:
              replicas_list.append(share)
              replicas_list.append({'name': 'fake_replica'})
  
          mock_notify.assert_not_called()
  
          manager = self.share_manager
          self.mock_object(manager, 'driver')
          self.mock_object(manager.db, 'share_get',
                           mock.Mock(return_value=share))
          self.mock_object(manager.db, 'share_update',
                           mock.Mock(return_value=share))
          self.mock_object(quota.QUOTAS, 'commit')
          self.mock_object(quota.QUOTAS, 'reserve')
          self.mock_object(manager.driver, 'shrink_share')
          self.mock_object(manager, '_get_share_server',
                           mock.Mock(return_value=fake_share_server))
          self.mock_object(manager.db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=replicas_list))
          reservation_params = {
              'gigabytes': -size_decrease,
              'project_id': share['project_id'],
              'share_type_id': None,
              'user_id': share['user_id'],
          }
          if supports_replication:
              reservation_params.update(
                  {'replica_gigabytes': -size_decrease * 2})
  
          self.share_manager.shrink_share(self.context, share_id, new_size)
  
          self.assertTrue(manager._get_share_server.called)
          manager.driver.shrink_share.assert_called_once_with(
              utils.IsAMatcher(models.ShareInstance),
              new_size, share_server=fake_share_server
          )
  
          quota.QUOTAS.reserve.assert_called_once_with(
              mock.ANY, **reservation_params,
          )
          quota.QUOTAS.commit.assert_called_once_with(
              mock.ANY, mock.ANY, project_id=share['project_id'],
              share_type_id=None, user_id=share['user_id'],
          )
          manager.db.share_update.assert_called_once_with(
              mock.ANY, share_id, shr_update
          )
  
          self.assert_notify_called(mock_notify,
                                    (['INFO', 'share.shrink.start'],
                                     ['INFO', 'share.shrink.end']))
          (self.share_manager.db.share_replicas_get_all_by_share.
              assert_called_once_with(mock.ANY, share['id']))
  
      def test_report_driver_status_driver_handles_ss_false(self):
          fake_stats = {'field': 'val'}
          fake_pool = {'name': 'pool1'}
          self.share_manager.last_capabilities = {'field': 'old_val'}
  
          self.mock_object(self.share_manager, 'driver', mock.Mock())
          driver = self.share_manager.driver
  
          driver.get_share_stats = mock.Mock(return_value=fake_stats)
          self.mock_object(db, 'share_server_get_all_by_host', mock.Mock())
          driver.driver_handles_share_servers = False
          driver.get_share_server_pools = mock.Mock(return_value=fake_pool)
  
          self.share_manager._report_driver_status(self.context)
  
          driver.get_share_stats.assert_called_once_with(
              refresh=True)
          self.assertFalse(db.share_server_get_all_by_host.called)
          self.assertFalse(driver.get_share_server_pools.called)
          self.assertEqual(fake_stats, self.share_manager.last_capabilities)
  
      def test_report_driver_status_driver_handles_ss(self):
          fake_stats = {'field': 'val'}
          fake_ss = {'id': '1234'}
          fake_pool = {'name': 'pool1'}
  
          self.mock_object(self.share_manager, 'driver', mock.Mock())
          driver = self.share_manager.driver
  
          driver.get_share_stats = mock.Mock(return_value=fake_stats)
          self.mock_object(db, 'share_server_get_all_by_host', mock.Mock(
              return_value=[fake_ss]))
          driver.driver_handles_share_servers = True
          driver.get_share_server_pools = mock.Mock(return_value=fake_pool)
  
          self.share_manager._report_driver_status(self.context)
  
          driver.get_share_stats.assert_called_once_with(refresh=True)
          # db.share_server_get_all_by_host.assert_called_once_with(
          #     self.context,
          #     self.share_manager.host)
          # driver.get_share_server_pools.assert_called_once_with(fake_ss)
          expected_stats = {
              'field': 'val',
              # 'server_pools_mapping': {
              #     '1234': fake_pool},
          }
          self.assertEqual(expected_stats, self.share_manager.last_capabilities)
  
      def test_report_driver_status_empty_share_stats(self):
          old_capabilities = {'field': 'old_val'}
          fake_pool = {'name': 'pool1'}
          self.share_manager.last_capabilities = old_capabilities
  
          self.mock_object(self.share_manager, 'driver', mock.Mock())
          driver = self.share_manager.driver
  
          driver.get_share_stats = mock.Mock(return_value={})
          self.mock_object(db, 'share_server_get_all_by_host', mock.Mock())
          driver.driver_handles_share_servers = True
          driver.get_share_server_pools = mock.Mock(return_value=fake_pool)
  
          self.share_manager._report_driver_status(self.context)
  
          driver.get_share_stats.assert_called_once_with(refresh=True)
          self.assertFalse(db.share_server_get_all_by_host.called)
          self.assertFalse(driver.get_share_server_pools.called)
          self.assertEqual(old_capabilities,
                           self.share_manager.last_capabilities)
  
      def test_create_share_group(self):
          fake_group = {
              'id': 'fake_id',
              'availability_zone_id': 'fake_az',
          }
          self.mock_object(self.share_manager.db, 'share_group_get',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_update',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.driver,
                           'create_share_group',
                           mock.Mock(return_value=None))
  
          self.share_manager.create_share_group(self.context, "fake_id")
  
          self.share_manager.db.share_group_update.assert_called_once_with(
              mock.ANY, 'fake_id', {
                  'status': constants.STATUS_AVAILABLE,
                  'created_at': mock.ANY,
                  'consistent_snapshot_support': None,
                  'availability_zone_id': fake_group['availability_zone_id'],
              }
          )
  
      def test_create_cg_with_share_network_driver_not_handles_servers(self):
          manager.CONF.set_default('driver_handles_share_servers', False)
          self.mock_object(
              self.share_manager.driver.configuration, 'safe_get',
              mock.Mock(return_value=False))
          cg_id = 'fake_group_id'
          share_network_id = 'fake_sn'
          fake_group = {'id': 'fake_id', 'share_network_id': share_network_id}
          self.mock_object(
              self.share_manager.db, 'share_group_get',
              mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_update')
  
          self.assertRaises(
              exception.ManilaException,
              self.share_manager.create_share_group, self.context, cg_id)
  
          self.share_manager.db.share_group_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), cg_id)
          self.share_manager.db.share_group_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), cg_id,
              {'status': constants.STATUS_ERROR})
  
      def test_create_sg_with_share_network_driver_handles_servers(self):
          manager.CONF.set_default('driver_handles_share_servers', True)
          self.mock_object(
              self.share_manager.driver.configuration, 'safe_get',
              mock.Mock(return_value=True))
          share_network_id = 'fake_sn'
          fake_group = {
              'id': 'fake_id',
              'share_network_id': share_network_id,
              'host': "fake_host",
              'availability_zone_id': 'fake_az',
          }
          fake_subnet = {
              'id': 'fake_subnet_id'
          }
          self.mock_object(
              self.share_manager.db, 'share_group_get',
              mock.Mock(return_value=fake_group))
          self.mock_object(
              self.share_manager.db, 'share_group_update',
              mock.Mock(return_value=fake_group))
          self.mock_object(
              self.share_manager.db,
              'share_network_subnet_get_by_availability_zone_id',
              mock.Mock(return_value=fake_subnet)
          )
          self.mock_object(
              self.share_manager, '_provide_share_server_for_share_group',
              mock.Mock(return_value=({}, fake_group)))
          self.mock_object(
              self.share_manager.driver, 'create_share_group',
              mock.Mock(return_value=None))
  
          self.share_manager.create_share_group(self.context, "fake_id")
  
          self.share_manager.db.share_group_update.assert_called_once_with(
              mock.ANY, 'fake_id', {
                  'status': constants.STATUS_AVAILABLE,
                  'created_at': mock.ANY,
                  'consistent_snapshot_support': None,
                  'availability_zone_id': fake_group['availability_zone_id'],
              }
          )
  
      def test_create_share_group_with_update(self):
          fake_group = {
              'id': 'fake_id',
              'availability_zone_id': 'fake_az',
          }
          self.mock_object(self.share_manager.db, 'share_group_get',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_update',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.driver,
                           'create_share_group',
                           mock.Mock(return_value={'foo': 'bar'}))
  
          self.share_manager.create_share_group(self.context, "fake_id")
  
          (self.share_manager.db.share_group_update.
              assert_any_call(mock.ANY, 'fake_id', {'foo': 'bar'}))
          self.share_manager.db.share_group_update.assert_any_call(
              mock.ANY, 'fake_id', {
                  'status': constants.STATUS_AVAILABLE,
                  'created_at': mock.ANY,
                  'consistent_snapshot_support': None,
                  'availability_zone_id': fake_group['availability_zone_id'],
              }
          )
  
      def test_create_share_group_with_error(self):
          fake_group = {
              'id': 'fake_id',
              'availability_zone_id': 'fake_az',
          }
          self.mock_object(self.share_manager.db, 'share_group_get',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_update',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.driver,
                           'create_share_group',
                           mock.Mock(side_effect=exception.Error))
  
          self.assertRaises(exception.Error,
                            self.share_manager.create_share_group,
                            self.context, "fake_id")
  
          self.share_manager.db.share_group_update.assert_called_once_with(
              mock.ANY, 'fake_id', {
                  'status': constants.STATUS_ERROR,
                  'consistent_snapshot_support': None,
                  'availability_zone_id': fake_group['availability_zone_id'],
              }
          )
  
      def test_create_share_group_from_sg_snapshot(self):
          fake_group = {
              'id': 'fake_id',
              'source_share_group_snapshot_id': 'fake_snap_id',
              'shares': [],
              'share_server_id': 'fake_ss_id',
              'availability_zone_id': 'fake_az',
          }
          fake_sn = {'id': 'fake_sn_id'}
          fake_sns = {'id': 'fake_sns_id', 'share_network_id': fake_sn['id']}
          fake_ss = {'id': 'fake_ss_id', 'share_network_subnet': fake_sns}
          fake_snap = {'id': 'fake_snap_id', 'share_group_snapshot_members': [],
                       'share_group': {'share_server_id': fake_ss['id']}}
          self.mock_object(self.share_manager.db, 'share_group_get',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_snapshot_get',
                           mock.Mock(return_value=fake_snap))
          self.mock_object(self.share_manager.db, 'share_server_get',
                           mock.Mock(
                               return_value=fake_ss))
          self.mock_object(self.share_manager.db, 'share_group_update',
                           mock.Mock(return_value=fake_group))
          mock_create_sg_from_sg_snap = self.mock_object(
              self.share_manager.driver,
              'create_share_group_from_share_group_snapshot',
              mock.Mock(return_value=(None, None)))
  
          self.share_manager.create_share_group(self.context, "fake_id")
  
          self.share_manager.db.share_group_update.assert_called_once_with(
              mock.ANY, 'fake_id',
              {'status': constants.STATUS_AVAILABLE,
               'created_at': mock.ANY,
               'availability_zone_id': fake_group['availability_zone_id'],
               'consistent_snapshot_support': None})
          self.share_manager.db.share_server_get(mock.ANY, 'fake_ss_id')
          mock_create_sg_from_sg_snap.assert_called_once_with(
              mock.ANY, fake_group, fake_snap, share_server=fake_ss)
  
      def test_create_sg_snapshot_share_network_driver_not_handles_servers(self):
          manager.CONF.set_default('driver_handles_share_servers', False)
          self.mock_object(
              self.share_manager.driver.configuration, 'safe_get',
              mock.Mock(return_value=False))
          sg_id = 'fake_share_group_id'
          share_network_id = 'fake_sn'
          fake_group = {
              'id': 'fake_id',
              'source_share_group_snapshot_id': 'fake_snap_id',
              'shares': [],
              'share_network_id': share_network_id,
              'host': "fake_host",
          }
          self.mock_object(
              self.share_manager.db, 'share_group_get',
              mock.Mock(return_value=fake_group))
          fake_snap = {'id': 'fake_snap_id', 'share_group_snapshot_members': []}
          self.mock_object(self.share_manager.db, 'share_group_snapshot_get',
                           mock.Mock(return_value=fake_snap))
          self.mock_object(self.share_manager.db, 'share_group_update')
  
          self.assertRaises(exception.ManilaException,
                            self.share_manager.create_share_group,
                            self.context, sg_id)
  
          self.share_manager.db.share_group_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), sg_id)
          self.share_manager.db.share_group_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), sg_id,
              {'status': constants.STATUS_ERROR})
  
      def test_create_share_group_from_sg_snapshot_share_network_dhss(self):
          manager.CONF.set_default('driver_handles_share_servers', True)
          self.mock_object(self.share_manager.driver.configuration, 'safe_get',
                           mock.Mock(return_value=True))
          share_network_id = 'fake_sn'
          share_network_subnet = {
              'id': 'fake_subnet_id'
          }
          fake_group = {
              'id': 'fake_id',
              'source_share_group_snapshot_id': 'fake_snap_id',
              'shares': [],
              'share_network_id': share_network_id,
              'availability_zone_id': 'fake_az',
          }
          fake_snap = {'id': 'fake_snap_id', 'share_group_snapshot_members': []}
          self.mock_object(self.share_manager.db, 'share_group_get',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_snapshot_get',
                           mock.Mock(return_value=fake_snap))
          self.mock_object(self.share_manager.db, 'share_group_update',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db,
                           'share_network_subnet_get_by_availability_zone_id',
                           mock.Mock(return_value=share_network_subnet))
          self.mock_object(
              self.share_manager, '_provide_share_server_for_share_group',
              mock.Mock(return_value=({}, fake_group)))
          self.mock_object(
              self.share_manager.driver,
              'create_share_group_from_share_group_snapshot',
              mock.Mock(return_value=(None, None)))
  
          self.share_manager.create_share_group(self.context, "fake_id")
  
          self.share_manager.db.share_group_update.assert_called_once_with(
              mock.ANY, 'fake_id',
              {'status': constants.STATUS_AVAILABLE,
               'created_at': mock.ANY,
               'consistent_snapshot_support': None,
               'availability_zone_id': fake_group['availability_zone_id']})
  
      def test_create_share_group_from_share_group_snapshot_with_update(self):
          fake_group = {
              'id': 'fake_id',
              'source_share_group_snapshot_id': 'fake_snap_id',
              'shares': [],
              'availability_zone_id': 'fake_az',
          }
          fake_snap = {'id': 'fake_snap_id', 'share_group_snapshot_members': []}
          self.mock_object(self.share_manager.db, 'share_group_get',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_snapshot_get',
                           mock.Mock(return_value=fake_snap))
          self.mock_object(self.share_manager.db, 'share_group_update',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.driver,
                           'create_share_group_from_share_group_snapshot',
                           mock.Mock(return_value=({'foo': 'bar'}, None)))
  
          self.share_manager.create_share_group(self.context, "fake_id")
  
          self.share_manager.db.share_group_update.assert_any_call(
              mock.ANY, 'fake_id', {'foo': 'bar'})
          self.share_manager.db.share_group_update.assert_any_call(
              mock.ANY, 'fake_id', {
                  'status': constants.STATUS_AVAILABLE,
                  'created_at': mock.ANY,
                  'consistent_snapshot_support': None,
                  'availability_zone_id': fake_group['availability_zone_id'],
              }
          )
  
      @ddt.data(constants.STATUS_AVAILABLE,
                constants.STATUS_CREATING_FROM_SNAPSHOT,
                None)
      def test_create_share_group_from_sg_snapshot_with_share_update_status(
              self, share_status):
          fake_share = {'id': 'fake_share_id'}
          # if share_status is not None:
          #     fake_share.update({'status': share_status})
  
          fake_export_locations = ['my_export_location']
          fake_group = {
              'id': 'fake_id',
              'source_share_group_snapshot_id': 'fake_snap_id',
              'shares': [fake_share],
              'availability_zone_id': 'fake_az',
          }
          fake_snap = {'id': 'fake_snap_id', 'share_group_snapshot_members': []}
          self.mock_object(self.share_manager.db, 'share_group_get',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_snapshot_get',
                           mock.Mock(return_value=fake_snap))
          self.mock_object(self.share_manager.db, 'share_group_update')
          self.mock_object(self.share_manager.db, 'share_instance_update')
          self.mock_object(self.share_manager.db,
                           'share_export_locations_update')
  
          fake_share_update = {'id': fake_share['id'],
                               'foo': 'bar',
                               'export_locations': fake_export_locations}
          if share_status is not None:
              fake_share_update.update({'status': share_status})
  
          self.mock_object(self.share_manager.driver,
                           'create_share_group_from_share_group_snapshot',
                           mock.Mock(return_value=(None, [fake_share_update])))
  
          self.share_manager.create_share_group(self.context, "fake_id")
  
          exp_progress = (
              '0%' if share_status == constants.STATUS_CREATING_FROM_SNAPSHOT
              else '100%')
          self.share_manager.db.share_instance_update.assert_any_call(
              mock.ANY,
              'fake_share_id',
              {'foo': 'bar',
               'status': share_status or constants.STATUS_AVAILABLE,
               'progress': exp_progress})
          self.share_manager.db.share_export_locations_update.assert_any_call(
              mock.ANY, 'fake_share_id', fake_export_locations)
          self.share_manager.db.share_group_update.assert_any_call(
              mock.ANY, 'fake_id', {
                  'status': constants.STATUS_AVAILABLE,
                  'created_at': mock.ANY,
                  'consistent_snapshot_support': None,
                  'availability_zone_id': fake_group['availability_zone_id'],
              }
          )
  
      def test_create_share_group_from_sg_snapshot_with_error(self):
          fake_group = {
              'id': 'fake_id',
              'source_share_group_snapshot_id': 'fake_snap_id',
              'shares': [],
              'availability_zone_id': 'fake_az',
          }
          fake_snap = {'id': 'fake_snap_id', 'share_group_snapshot_members': []}
          self.mock_object(self.share_manager.db, 'share_group_get',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_snapshot_get',
                           mock.Mock(return_value=fake_snap))
          self.mock_object(self.share_manager.db,
                           'share_instances_get_all_by_share_group_id',
                           mock.Mock(return_value=[]))
          self.mock_object(self.share_manager.db, 'share_group_update',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.driver,
                           'create_share_group_from_share_group_snapshot',
                           mock.Mock(side_effect=exception.Error))
  
          self.assertRaises(exception.Error,
                            self.share_manager.create_share_group,
                            self.context, "fake_id")
  
          self.share_manager.db.share_group_update.assert_called_once_with(
              mock.ANY, 'fake_id', {
                  'status': constants.STATUS_ERROR,
                  'consistent_snapshot_support': None,
                  'availability_zone_id': fake_group['availability_zone_id'],
              }
          )
  
      def test_create_share_group_from_sg_snapshot_with_invalid_status(self):
          fake_share = {'id': 'fake_share_id',
                        'status': constants.STATUS_CREATING}
          fake_export_locations = ['my_export_location']
          fake_group = {
              'id': 'fake_id',
              'source_share_group_snapshot_id': 'fake_snap_id',
              'shares': [fake_share],
              'availability_zone_id': 'fake_az',
          }
          fake_snap = {'id': 'fake_snap_id', 'share_group_snapshot_members': []}
          self.mock_object(self.share_manager.db, 'share_group_get',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_snapshot_get',
                           mock.Mock(return_value=fake_snap))
          self.mock_object(self.share_manager.db,
                           'share_instances_get_all_by_share_group_id',
                           mock.Mock(return_value=[]))
          self.mock_object(self.share_manager.db, 'share_group_update',
                           mock.Mock(return_value=fake_group))
          fake_share_update_list = [{'id': fake_share['id'],
                                     'status': fake_share['status'],
                                     'foo': 'bar',
                                     'export_locations': fake_export_locations}]
          self.mock_object(self.share_manager.driver,
                           'create_share_group_from_share_group_snapshot',
                           mock.Mock(
                               return_value=(None, fake_share_update_list)))
  
          self.assertRaises(exception.InvalidShareInstance,
                            self.share_manager.create_share_group,
                            self.context, "fake_id")
  
          self.share_manager.db.share_group_update.assert_called_once_with(
              mock.ANY, 'fake_id', {
                  'status': constants.STATUS_ERROR,
                  'consistent_snapshot_support': None,
                  'availability_zone_id': fake_group['availability_zone_id'],
              }
          )
  
      def test_create_share_group_from_sg_snapshot_with_share_error(self):
          fake_share = {'id': 'fake_share_id'}
          fake_group = {
              'id': 'fake_id',
              'source_share_group_snapshot_id': 'fake_snap_id',
              'shares': [fake_share],
              'availability_zone_id': 'fake_az',
          }
          fake_snap = {'id': 'fake_snap_id', 'share_group_snapshot_members': []}
          self.mock_object(self.share_manager.db, 'share_group_get',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_snapshot_get',
                           mock.Mock(return_value=fake_snap))
          self.mock_object(self.share_manager.db,
                           'share_instances_get_all_by_share_group_id',
                           mock.Mock(return_value=[fake_share]))
          self.mock_object(self.share_manager.db, 'share_group_update')
          self.mock_object(self.share_manager.db, 'share_instance_update')
          self.mock_object(self.share_manager.driver,
                           'create_share_group_from_share_group_snapshot',
                           mock.Mock(side_effect=exception.Error))
  
          self.assertRaises(exception.Error,
                            self.share_manager.create_share_group,
                            self.context, "fake_id")
  
          self.share_manager.db.share_instance_update.assert_any_call(
              mock.ANY, 'fake_share_id', {'status': constants.STATUS_ERROR})
          self.share_manager.db.share_group_update.assert_called_once_with(
              mock.ANY, 'fake_id', {
                  'status': constants.STATUS_ERROR,
                  'consistent_snapshot_support': None,
                  'availability_zone_id': fake_group['availability_zone_id'],
              }
          )
  
      def test_delete_share_group(self):
          fake_group = {'id': 'fake_id'}
          self.mock_object(self.share_manager.db, 'share_group_get',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_update',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_destroy',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.driver,
                           'delete_share_group',
                           mock.Mock(return_value=None))
  
          self.share_manager.delete_share_group(self.context, "fake_id")
  
          self.share_manager.db.share_group_destroy.assert_called_once_with(
              mock.ANY, 'fake_id')
  
      def test_delete_share_group_with_update(self):
          fake_group = {'id': 'fake_id'}
          self.mock_object(self.share_manager.db, 'share_group_get',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_update',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_destroy',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.driver,
                           'delete_share_group',
                           mock.Mock(return_value={'foo': 'bar'}))
  
          self.share_manager.delete_share_group(self.context, "fake_id")
  
          self.share_manager.db.share_group_update.assert_called_once_with(
              mock.ANY, 'fake_id', {'foo': 'bar'})
          self.share_manager.db.share_group_destroy.assert_called_once_with(
              mock.ANY, 'fake_id')
  
      def test_delete_share_group_with_error(self):
          fake_group = {'id': 'fake_id'}
          self.mock_object(self.share_manager.db, 'share_group_get',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.db, 'share_group_update',
                           mock.Mock(return_value=fake_group))
          self.mock_object(self.share_manager.driver,
                           'delete_share_group',
                           mock.Mock(side_effect=exception.Error))
  
          self.assertRaises(exception.Error,
                            self.share_manager.delete_share_group,
                            self.context, "fake_id")
  
          self.share_manager.db.share_group_update.assert_called_once_with(
              mock.ANY, 'fake_id', {'status': constants.STATUS_ERROR})
  
      def test_create_share_group_snapshot(self):
          fake_snap = {
              'id': 'fake_snap_id',
              'share_group': {},
              'share_group_snapshot_members': [],
          }
          self.mock_object(
              self.share_manager.db, 'share_group_snapshot_get',
              mock.Mock(return_value=fake_snap))
          mock_sg_snap_update = self.mock_object(
              self.share_manager.db, 'share_group_snapshot_update',
              mock.Mock(return_value=fake_snap))
          self.mock_object(
              self.share_manager.driver,
              'create_share_group_snapshot',
              mock.Mock(return_value=(None, None)))
  
          self.share_manager.create_share_group_snapshot(
              self.context, fake_snap['id'])
  
          mock_sg_snap_update.assert_called_once_with(
              mock.ANY, fake_snap['id'],
              {'status': constants.STATUS_AVAILABLE, 'updated_at': mock.ANY})
  
      def test_create_share_group_snapshot_with_update(self):
          fake_snap = {'id': 'fake_snap_id', 'share_group': {},
                       'share_group_snapshot_members': []}
          self.mock_object(self.share_manager.db, 'share_group_snapshot_get',
                           mock.Mock(return_value=fake_snap))
          self.mock_object(self.share_manager.db, 'share_group_snapshot_update',
                           mock.Mock(return_value=fake_snap))
          self.mock_object(self.share_manager.driver,
                           'create_share_group_snapshot',
                           mock.Mock(return_value=({'foo': 'bar'}, None)))
  
          self.share_manager.create_share_group_snapshot(
              self.context, fake_snap['id'])
  
          self.share_manager.db.share_group_snapshot_update.assert_any_call(
              mock.ANY, 'fake_snap_id', {'foo': 'bar'})
          self.share_manager.db.share_group_snapshot_update.assert_any_call(
              mock.ANY, fake_snap['id'],
              {'status': constants.STATUS_AVAILABLE, 'updated_at': mock.ANY})
  
      def test_create_share_group_snapshot_with_member_update(self):
          fake_member1 = {'id': 'fake_member_id_1', 'share_instance_id': 'si_1'}
          fake_member2 = {'id': 'fake_member_id_2', 'share_instance_id': 'si_2'}
          fake_member3 = {'id': 'fake_member_id_3', 'share_instance_id': 'si_3'}
          fake_member_update1 = {
              'id': fake_member1['id'],
              'provider_location': 'fake_provider_location_1',
              'size': 13,
              'export_locations': ['fake_el_1_1', 'fake_el_1_2'],
              'should_not_be_used_k1': 'should_not_be_used_v1',
          }
          fake_member_update2 = {
              'id': fake_member2['id'],
              'provider_location': 'fake_provider_location_2',
              'size': 31,
              'export_locations': ['fake_el_2_1', 'fake_el_2_2'],
              'status': 'fake_status_for_update',
              'should_not_be_used_k2': 'should_not_be_used_k2',
          }
          fake_member_update3 = {
              'provider_location': 'fake_provider_location_3',
              'size': 42,
              'export_locations': ['fake_el_3_1', 'fake_el_3_2'],
              'should_not_be_used_k3': 'should_not_be_used_k3',
          }
          expected_member_update1 = {
              'id': fake_member_update1['id'],
              'provider_location': fake_member_update1['provider_location'],
              'size': fake_member_update1['size'],
          }
          expected_member_update2 = {
              'id': fake_member_update2['id'],
              'provider_location': fake_member_update2['provider_location'],
              'size': fake_member_update2['size'],
              'status': fake_member_update2['status'],
          }
          fake_snap = {
              'id': 'fake_snap_id',
              'share_group': {},
              'share_group_snapshot_members': [
                  fake_member1, fake_member2, fake_member3],
          }
          self.mock_object(
              self.share_manager.db, 'share_group_snapshot_get',
              mock.Mock(return_value=fake_snap))
          mock_sg_snapshot_update = self.mock_object(
              self.share_manager.db, 'share_group_snapshot_update',
              mock.Mock(return_value=fake_snap))
          mock_sg_snapshot_member_update = self.mock_object(
              self.share_manager.db, 'share_group_snapshot_member_update')
          self.mock_object(
              self.share_manager.db, 'share_instance_get',
              mock.Mock(return_value={'id': 'blah'}))
          self.mock_object(
              timeutils, 'utcnow', mock.Mock(side_effect=range(1, 10)))
          mock_driver_create_sg_snapshot = self.mock_object(
              self.share_manager.driver, 'create_share_group_snapshot',
              mock.Mock(return_value=(
                  None, [fake_member_update1, fake_member_update2,
                         fake_member_update3])))
  
          self.share_manager.create_share_group_snapshot(
              self.context, fake_snap['id'])
  
          mock_driver_create_sg_snapshot.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              fake_snap, share_server=None)
          mock_sg_snapshot_update.assert_called_once_with(
              mock.ANY, fake_snap['id'],
              {'status': constants.STATUS_AVAILABLE, 'updated_at': mock.ANY})
          mock_sg_snapshot_member_update.assert_has_calls([
              mock.call(
                  utils.IsAMatcher(context.RequestContext),
                  expected_member_update1['id'],
                  {'provider_location': expected_member_update1[
                      'provider_location'],
                   'size': expected_member_update1['size'],
                   'updated_at': 1,
                   'status': manager.constants.STATUS_AVAILABLE}),
              mock.call(
                  utils.IsAMatcher(context.RequestContext),
                  expected_member_update2['id'],
                  {'provider_location': expected_member_update2[
                      'provider_location'],
                   'size': expected_member_update2['size'],
                   'updated_at': 1,
                   'status': expected_member_update2['status']}),
          ])
  
      def test_create_group_snapshot_with_error(self):
          fake_snap = {'id': 'fake_snap_id', 'share_group': {},
                       'share_group_snapshot_members': []}
          self.mock_object(
              self.share_manager.db, 'share_group_snapshot_get',
              mock.Mock(return_value=fake_snap))
          mock_sg_snap_update = self.mock_object(
              self.share_manager.db, 'share_group_snapshot_update',
              mock.Mock(return_value=fake_snap))
          self.mock_object(
              self.share_manager.driver,
              'create_share_group_snapshot',
              mock.Mock(side_effect=exception.Error))
  
          self.assertRaises(
              exception.Error,
              self.share_manager.create_share_group_snapshot,
              self.context, fake_snap['id'])
  
          mock_sg_snap_update.assert_called_once_with(
              mock.ANY, fake_snap['id'], {'status': constants.STATUS_ERROR})
  
      def test_connection_get_info(self):
          share_instance = {'share_server_id': 'fake_server_id'}
          share_instance_id = 'fake_id'
          share_server = 'fake_share_server'
          connection_info = 'fake_info'
  
          # mocks
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(return_value=share_instance))
          self.mock_object(self.share_manager.db, 'share_server_get',
                           mock.Mock(return_value=share_server))
          self.mock_object(self.share_manager.driver, 'connection_get_info',
                           mock.Mock(return_value=connection_info))
  
          # run
          result = self.share_manager.connection_get_info(
              self.context, share_instance_id)
  
          # asserts
          self.assertEqual(connection_info, result)
  
          self.share_manager.db.share_instance_get.assert_called_once_with(
              self.context, share_instance_id, with_share_data=True)
  
          self.share_manager.driver.connection_get_info.assert_called_once_with(
              self.context, share_instance, share_server)
  
      @ddt.data(True, False)
      def test_migration_start(self, success):
  
          instance = db_utils.create_share_instance(
              share_id='fake_id',
              status=constants.STATUS_AVAILABLE,
              share_server_id='fake_server_id',
              host='fake@backend#pool')
          share = db_utils.create_share(id='fake_id', instances=[instance])
          fake_service = {'availability_zone_id': 'fake_az_id'}
          host = 'fake2@backend#pool'
  
          # mocks
          self.mock_object(self.share_manager.db, 'share_get',
                           mock.Mock(return_value=share))
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(return_value=instance))
          self.mock_object(self.share_manager.db, 'share_update')
          self.mock_object(self.share_manager.db, 'share_instance_update')
          self.mock_object(self.share_manager, '_migration_start_driver',
                           mock.Mock(return_value=success))
          self.mock_object(self.share_manager.db, 'service_get_by_args',
                           mock.Mock(return_value=fake_service))
  
          if not success:
              self.mock_object(
                  self.share_manager, '_migration_start_host_assisted')
  
          # run
          self.share_manager.migration_start(
              self.context, 'fake_id', host, False, False, False, False, False,
              'fake_net_id', 'fake_type_id')
  
          # asserts
          self.share_manager.db.share_get.assert_called_once_with(
              self.context, share['id'])
          self.share_manager.db.share_instance_get.assert_called_once_with(
              self.context, instance['id'], with_share_data=True)
  
          share_update_calls = [
              mock.call(
                  self.context, share['id'],
                  {'task_state': constants.TASK_STATE_MIGRATION_IN_PROGRESS}),
          ]
  
          if not success:
              share_update_calls.append(mock.call(
                  self.context, share['id'],
                  {'task_state': constants.TASK_STATE_MIGRATION_IN_PROGRESS}))
  
          self.share_manager.db.share_update.assert_has_calls(share_update_calls)
          self.share_manager._migration_start_driver.assert_called_once_with(
              self.context, share, instance, host, False, False, False, False,
              'fake_net_id', 'fake_az_id', 'fake_type_id')
          if not success:
              (self.share_manager._migration_start_host_assisted.
                  assert_called_once_with(
                      self.context, share, instance, host, 'fake_net_id',
                      'fake_az_id', 'fake_type_id'))
          self.share_manager.db.service_get_by_args.assert_called_once_with(
              self.context, 'fake2@backend', 'manila-share')
  
      @ddt.data({'writable': False, 'preserve_metadata': False,
                 'nondisruptive': False, 'preserve_snapshots': True,
                 'has_snapshots': False},
                {'writable': False, 'preserve_metadata': False,
                 'nondisruptive': True, 'preserve_snapshots': False,
                 'has_snapshots': False},
                {'writable': False, 'preserve_metadata': True,
                 'nondisruptive': False, 'preserve_snapshots': False,
                 'has_snapshots': False},
                {'writable': True, 'preserve_metadata': False,
                 'nondisruptive': False, 'preserve_snapshots': False,
                 'has_snapshots': False},
                {'writable': False, 'preserve_metadata': False,
                 'nondisruptive': False, 'preserve_snapshots': False,
                 'has_snapshots': True}
                )
      @ddt.unpack
      def test_migration_start_prevent_host_assisted(
              self, writable, preserve_metadata, nondisruptive,
              preserve_snapshots, has_snapshots):
  
          share = db_utils.create_share()
          instance = share.instance
          host = 'fake@backend#pool'
          fake_service = {'availability_zone_id': 'fake_az_id'}
          if has_snapshots:
              snapshot = db_utils.create_snapshot(share_id=share['id'])
              self.mock_object(
                  self.share_manager.db, 'share_snapshot_get_all_for_share',
                  mock.Mock(return_value=[snapshot]))
  
          # mocks
          self.mock_object(self.share_manager, '_reset_read_only_access_rules')
          self.mock_object(self.share_manager.db, 'service_get_by_args',
                           mock.Mock(return_value=fake_service))
          self.mock_object(self.share_manager.db, 'share_update')
          self.mock_object(self.share_manager.db, 'share_instance_update')
          self.mock_object(self.share_manager.db, 'share_get',
                           mock.Mock(return_value=share))
  
          # run
          self.assertRaises(
              exception.ShareMigrationFailed, self.share_manager.migration_start,
              self.context, 'share_id', host, True, writable, preserve_metadata,
              nondisruptive, preserve_snapshots, 'fake_net_id')
  
          self.share_manager.db.share_update.assert_has_calls([
              mock.call(
                  self.context, 'share_id',
                  {'task_state': constants.TASK_STATE_MIGRATION_IN_PROGRESS}),
              mock.call(
                  self.context, 'share_id',
                  {'task_state': constants.TASK_STATE_MIGRATION_ERROR}),
          ])
          self.share_manager.db.share_instance_update.assert_called_once_with(
              self.context, instance['id'],
              {'status': constants.STATUS_AVAILABLE})
          self.share_manager.db.share_get.assert_called_once_with(
              self.context, 'share_id')
          self.share_manager.db.service_get_by_args.assert_called_once_with(
              self.context, 'fake@backend', 'manila-share')
          (self.share_manager._reset_read_only_access_rules.
           assert_called_once_with(self.context, instance['id']))
  
      def test_migration_start_exception(self):
  
          instance = db_utils.create_share_instance(
              share_id='fake_id',
              status=constants.STATUS_AVAILABLE,
              share_server_id='fake_server_id',
              host='fake@backend#pool')
          share = db_utils.create_share(id='fake_id', instances=[instance])
          host = 'fake2@backend#pool'
          fake_service = {'availability_zone_id': 'fake_az_id'}
  
          # mocks
          self.mock_object(self.share_manager.db, 'service_get_by_args',
                           mock.Mock(return_value=fake_service))
          self.mock_object(self.share_manager.db, 'share_get',
                           mock.Mock(return_value=share))
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(return_value=instance))
          self.mock_object(self.share_manager.db, 'share_update')
          self.mock_object(self.share_manager.db, 'share_instance_update')
          self.mock_object(self.share_manager, '_migration_start_driver',
                           mock.Mock(side_effect=Exception('fake_exc_1')))
          self.mock_object(self.share_manager, '_migration_start_host_assisted',
                           mock.Mock(side_effect=Exception('fake_exc_2')))
          self.mock_object(self.share_manager, '_reset_read_only_access_rules')
  
          # run
          self.assertRaises(
              exception.ShareMigrationFailed,
              self.share_manager.migration_start,
              self.context, 'fake_id', host, False, False, False, False, False,
              'fake_net_id', 'fake_type_id')
  
          # asserts
          self.share_manager.db.share_get.assert_called_once_with(
              self.context, share['id'])
          self.share_manager.db.share_instance_get.assert_called_once_with(
              self.context, instance['id'], with_share_data=True)
  
          share_update_calls = [
              mock.call(
                  self.context, share['id'],
                  {'task_state': constants.TASK_STATE_MIGRATION_IN_PROGRESS}),
              mock.call(
                  self.context, share['id'],
                  {'task_state': constants.TASK_STATE_MIGRATION_ERROR})
          ]
  
          (self.share_manager._reset_read_only_access_rules.
           assert_called_once_with(self.context, instance['id']))
          self.share_manager.db.share_update.assert_has_calls(share_update_calls)
          self.share_manager.db.share_instance_update.assert_called_once_with(
              self.context, instance['id'],
              {'status': constants.STATUS_AVAILABLE})
          self.share_manager._migration_start_driver.assert_called_once_with(
              self.context, share, instance, host, False, False, False, False,
              'fake_net_id', 'fake_az_id', 'fake_type_id')
          self.share_manager.db.service_get_by_args.assert_called_once_with(
              self.context, 'fake2@backend', 'manila-share')
  
      @ddt.data(None, Exception('fake'))
      def test__migration_start_host_assisted(self, exc):
          share_server = db_utils.create_share_server()
          instance = db_utils.create_share_instance(
              share_id='fake_id',
              status=constants.STATUS_AVAILABLE,
              share_server_id=share_server['id'])
          new_instance = db_utils.create_share_instance(
              share_id='new_fake_id',
              status=constants.STATUS_AVAILABLE)
          share = db_utils.create_share(id='fake_id', instances=[instance])
          src_connection_info = 'src_fake_info'
          dest_connection_info = 'dest_fake_info'
          instance_updates = [
              mock.call(
                  self.context, instance['id'],
                  {'cast_rules_to_readonly': True})
          ]
          # mocks
          helper = mock.Mock()
          self.mock_object(migration_api, 'ShareMigrationHelper',
                           mock.Mock(return_value=helper))
          self.mock_object(helper, 'cleanup_new_instance')
          self.mock_object(self.share_manager.db, 'share_server_get',
                           mock.Mock(return_value=share_server))
          self.mock_object(self.share_manager.db, 'share_instance_update',
                           mock.Mock(return_value=share_server))
          self.mock_object(self.share_manager.access_helper,
                           'get_and_update_share_instance_access_rules')
          self.mock_object(self.share_manager.access_helper,
                           'update_access_rules')
          self.mock_object(utils, 'wait_for_access_update')
  
          if exc is None:
              self.mock_object(helper,
                               'create_instance_and_wait',
                               mock.Mock(return_value=new_instance))
              self.mock_object(self.share_manager.driver, 'connection_get_info',
                               mock.Mock(return_value=src_connection_info))
              self.mock_object(rpcapi.ShareAPI, 'connection_get_info',
                               mock.Mock(return_value=dest_connection_info))
              self.mock_object(data_rpc.DataAPI, 'migration_start',
                               mock.Mock(side_effect=Exception('fake')))
              self.mock_object(helper, 'cleanup_new_instance')
              instance_updates.append(
                  mock.call(self.context, new_instance['id'],
                            {'status': constants.STATUS_MIGRATING_TO}))
          else:
              self.mock_object(helper, 'create_instance_and_wait',
                               mock.Mock(side_effect=exc))
  
          # run
          self.assertRaises(
              exception.ShareMigrationFailed,
              self.share_manager._migration_start_host_assisted,
              self.context, share, instance, 'fake_host', 'fake_net_id',
              'fake_az_id', 'fake_type_id')
  
          # asserts
          self.share_manager.db.share_server_get.assert_has_calls([
              mock.call(utils.IsAMatcher(context.RequestContext),
                        instance['share_server_id']),
              mock.call(utils.IsAMatcher(context.RequestContext),
                        instance['share_server_id'])
              ])
          (self.share_manager.access_helper.update_access_rules.
           assert_called_once_with(
               self.context, instance['id'], share_server=share_server))
          helper.create_instance_and_wait.assert_called_once_with(
              share, 'fake_host', 'fake_net_id', 'fake_az_id', 'fake_type_id')
          utils.wait_for_access_update.assert_called_once_with(
              self.context, self.share_manager.db, instance,
              self.share_manager.migration_wait_access_rules_timeout)
  
          if exc is None:
              (self.share_manager.driver.connection_get_info.
                  assert_called_once_with(self.context, instance, share_server))
              rpcapi.ShareAPI.connection_get_info.assert_called_once_with(
                  self.context, new_instance)
              data_rpc.DataAPI.migration_start.assert_called_once_with(
                  self.context, share['id'], ['lost+found'], instance['id'],
                  new_instance['id'], src_connection_info, dest_connection_info)
              helper.cleanup_new_instance.assert_called_once_with(new_instance)
  
      @ddt.data({'share_network_id': 'fake_net_id', 'exc': None,
                 'has_snapshots': True},
                {'share_network_id': None, 'exc': Exception('fake'),
                 'has_snapshots': True},
                {'share_network_id': None, 'exc': None, 'has_snapshots': False})
      @ddt.unpack
      def test__migration_start_driver(
              self, exc, share_network_id, has_snapshots):
          fake_dest_host = 'fake_host'
          src_server = db_utils.create_share_server()
          if share_network_id:
              dest_server = db_utils.create_share_server()
          else:
              dest_server = None
          share = db_utils.create_share(
              id='fake_id',
              share_server_id='fake_src_server_id',
              share_network_id=share_network_id)
          migrating_instance = db_utils.create_share_instance(
              share_id='fake_id',
              share_network_id=share_network_id)
          if has_snapshots:
              snapshot = db_utils.create_snapshot(
                  status=(constants.STATUS_AVAILABLE if not exc
                          else constants.STATUS_ERROR),
                  share_id=share['id'])
              migrating_snap_instance = db_utils.create_snapshot(
                  status=constants.STATUS_MIGRATING,
                  share_id=share['id'])
              dest_snap_instance = db_utils.create_snapshot_instance(
                  status=constants.STATUS_AVAILABLE,
                  snapshot_id=snapshot['id'],
                  share_instance_id=migrating_instance['id'])
              snapshot_mappings = {snapshot.instance['id']: dest_snap_instance}
          else:
              snapshot_mappings = {}
          src_instance = share.instance
          compatibility = {
              'compatible': True,
              'writable': False,
              'preserve_metadata': False,
              'nondisruptive': False,
              'preserve_snapshots': has_snapshots,
          }
  
          # mocks
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(return_value=migrating_instance))
          self.mock_object(self.share_manager.db, 'share_server_get',
                           mock.Mock(return_value=src_server))
          self.mock_object(self.share_manager.driver,
                           'migration_check_compatibility',
                           mock.Mock(return_value=compatibility))
          self.mock_object(
              api.API, 'create_share_instance_and_get_request_spec',
              mock.Mock(return_value=({}, migrating_instance)))
          self.mock_object(self.share_manager.db, 'share_instance_update')
          self.mock_object(self.share_manager.db, 'share_update')
          self.mock_object(rpcapi.ShareAPI, 'provide_share_server',
                           mock.Mock(return_value='fake_dest_share_server_id'))
          self.mock_object(rpcapi.ShareAPI, 'create_share_server')
          self.mock_object(
              migration_api.ShareMigrationHelper, 'wait_for_share_server',
              mock.Mock(return_value=dest_server))
          self.mock_object(
              self.share_manager.db, 'share_snapshot_get_all_for_share',
              mock.Mock(return_value=[snapshot] if has_snapshots else []))
          if has_snapshots:
              self.mock_object(
                  self.share_manager.db, 'share_snapshot_instance_create',
                  mock.Mock(return_value=dest_snap_instance))
              self.mock_object(
                  self.share_manager.db, 'share_snapshot_instance_update')
              self.mock_object(
                  self.share_manager.db,
                  'share_snapshot_instance_get_all_with_filters',
                  mock.Mock(return_value=[migrating_snap_instance]))
          self.mock_object(self.share_manager.driver, 'migration_start')
          self.mock_object(self.share_manager, '_migration_delete_instance')
          self.mock_object(self.share_manager, 'update_access_for_instances')
          self.mock_object(utils, 'wait_for_access_update')
  
          # run
          if exc:
              self.assertRaises(
                  exception.ShareMigrationFailed,
                  self.share_manager._migration_start_driver,
                  self.context, share, src_instance, fake_dest_host, False,
                  False, False, False, share_network_id, 'fake_az_id',
                  'fake_type_id')
          else:
              result = self.share_manager._migration_start_driver(
                  self.context, share, src_instance, fake_dest_host, False,
                  False, False, False, share_network_id, 'fake_az_id',
                  'fake_type_id')
  
          # asserts
          if not exc:
              self.assertTrue(result)
              self.share_manager.db.share_update.assert_has_calls([
                  mock.call(
                      self.context, share['id'],
                      {'task_state':
                       constants.TASK_STATE_MIGRATION_DRIVER_STARTING}),
                  mock.call(
                      self.context, share['id'],
                      {'task_state':
                       constants.TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS})
              ])
              (self.share_manager.db.share_instance_update.assert_has_calls([
                  mock.call(self.context, migrating_instance['id'],
                            {'status': constants.STATUS_MIGRATING_TO}),
                  mock.call(self.context, src_instance['id'],
                            {'cast_rules_to_readonly': True})]))
              (self.share_manager.update_access_for_instances.
               assert_called_once_with(self.context, [src_instance['id']],
                                       share_server_id=src_server['id']))
              self.share_manager.driver.migration_start.assert_called_once_with(
                  self.context, src_instance, migrating_instance,
                  [snapshot.instance] if has_snapshots else [],
                  snapshot_mappings, src_server, dest_server)
  
          self.share_manager.db.share_instance_get.assert_called_once_with(
              self.context, migrating_instance['id'], with_share_data=True)
          self.share_manager.db.share_server_get.assert_called_once_with(
              self.context, 'fake_src_server_id')
          (api.API.create_share_instance_and_get_request_spec.
           assert_called_once_with(self.context, share, 'fake_az_id', None,
                                   'fake_host', share_network_id,
                                   'fake_type_id'))
          (self.share_manager.driver.migration_check_compatibility.
           assert_called_once_with(self.context, src_instance,
                                   migrating_instance, src_server, dest_server))
  
          (self.share_manager.db.share_snapshot_get_all_for_share.
           assert_called_once_with(self.context, share['id']))
  
          if share_network_id:
              (rpcapi.ShareAPI.provide_share_server.
               assert_called_once_with(
                   self.context, migrating_instance, share_network_id))
              rpcapi.ShareAPI.create_share_server.assert_called_once_with(
                  self.context, migrating_instance, 'fake_dest_share_server_id')
              (migration_api.ShareMigrationHelper.wait_for_share_server.
               assert_called_once_with('fake_dest_share_server_id'))
          if exc:
              (self.share_manager._migration_delete_instance.
               assert_called_once_with(self.context, migrating_instance['id']))
              if has_snapshots:
                  (self.share_manager.db.share_snapshot_instance_update.
                   assert_called_once_with(
                       self.context, migrating_snap_instance['id'],
                       {'status': constants.STATUS_AVAILABLE}))
                  (self.share_manager.db.
                   share_snapshot_instance_get_all_with_filters(
                       self.context,
                       {'share_instance_ids': [src_instance['id']]}))
          else:
              if has_snapshots:
                  snap_data = {
                      'status': constants.STATUS_MIGRATING_TO,
                      'progress': '0%',
                      'share_instance_id': migrating_instance['id'],
                  }
  
                  (self.share_manager.db.share_snapshot_instance_create.
                   assert_called_once_with(self.context, snapshot['id'],
                                           snap_data))
                  (self.share_manager.db.share_snapshot_instance_update.
                   assert_called_once_with(
                       self.context, snapshot.instance['id'],
                       {'status': constants.STATUS_MIGRATING}))
  
      @ddt.data({'writable': False, 'preserve_metadata': True,
                 'nondisruptive': True, 'compatible': True,
                 'preserve_snapshots': True, 'has_snapshots': False},
                {'writable': True, 'preserve_metadata': False,
                 'nondisruptive': True, 'compatible': True,
                 'preserve_snapshots': True, 'has_snapshots': False},
                {'writable': True, 'preserve_metadata': True,
                 'nondisruptive': False, 'compatible': True,
                 'preserve_snapshots': True, 'has_snapshots': False},
                {'writable': True, 'preserve_metadata': True,
                 'nondisruptive': True, 'compatible': False,
                 'preserve_snapshots': True, 'has_snapshots': False},
                {'writable': True, 'preserve_metadata': True,
                 'nondisruptive': True, 'compatible': True,
                 'preserve_snapshots': False, 'has_snapshots': False},
                {'writable': True, 'preserve_metadata': True,
                 'nondisruptive': True, 'compatible': True,
                 'preserve_snapshots': False, 'has_snapshots': True})
      @ddt.unpack
      def test__migration_start_driver_not_compatible(
              self, compatible, writable, preserve_metadata, nondisruptive,
              preserve_snapshots, has_snapshots):
  
          share = db_utils.create_share()
          src_instance = db_utils.create_share_instance(
              share_id='fake_id',
              share_server_id='src_server_id',
              share_network_id='fake_share_network_id')
          fake_dest_host = 'fake_host'
          src_server = db_utils.create_share_server()
          dest_server = db_utils.create_share_server()
          migrating_instance = db_utils.create_share_instance(
              share_id='fake_id',
              share_network_id='fake_net_id')
          compatibility = {
              'compatible': compatible,
              'writable': writable,
              'preserve_metadata': preserve_metadata,
              'nondisruptive': nondisruptive,
              'preserve_snapshots': preserve_snapshots,
          }
          snapshot = db_utils.create_snapshot(share_id=share['id'])
  
          # mocks
          self.mock_object(self.share_manager.db, 'share_server_get',
                           mock.Mock(return_value=src_server))
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(return_value=migrating_instance))
          self.mock_object(
              api.API, 'create_share_instance_and_get_request_spec',
              mock.Mock(return_value=({}, migrating_instance)))
          self.mock_object(rpcapi.ShareAPI, 'provide_share_server',
                           mock.Mock(return_value='fake_dest_share_server_id'))
          self.mock_object(rpcapi.ShareAPI, 'create_share_server')
          self.mock_object(
              migration_api.ShareMigrationHelper, 'wait_for_share_server',
              mock.Mock(return_value=dest_server))
          self.mock_object(self.share_manager, '_migration_delete_instance')
          self.mock_object(self.share_manager.driver,
                           'migration_check_compatibility',
                           mock.Mock(return_value=compatibility))
          self.mock_object(utils, 'wait_for_access_update')
          self.mock_object(
              self.share_manager.db, 'share_snapshot_get_all_for_share',
              mock.Mock(return_value=[snapshot] if has_snapshots else []))
  
          # run
          self.assertRaises(
              exception.ShareMigrationFailed,
              self.share_manager._migration_start_driver,
              self.context, share, src_instance, fake_dest_host, True, True,
              True, not has_snapshots, 'fake_net_id', 'fake_az_id',
              'fake_new_type_id')
  
          # asserts
          self.share_manager.db.share_server_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), 'src_server_id')
          self.share_manager.db.share_instance_get.assert_called_once_with(
              self.context, migrating_instance['id'], with_share_data=True)
          (rpcapi.ShareAPI.provide_share_server.
           assert_called_once_with(
               self.context, migrating_instance, 'fake_net_id'))
          rpcapi.ShareAPI.create_share_server.assert_called_once_with(
              self.context, migrating_instance, 'fake_dest_share_server_id')
          (migration_api.ShareMigrationHelper.wait_for_share_server.
           assert_called_once_with('fake_dest_share_server_id'))
          (api.API.create_share_instance_and_get_request_spec.
           assert_called_once_with(self.context, share, 'fake_az_id', None,
                                   'fake_host', 'fake_net_id',
                                   'fake_new_type_id'))
          self.share_manager._migration_delete_instance.assert_called_once_with(
              self.context, migrating_instance['id'])
  
      @ddt.data(Exception('fake'), False, True)
      def test_migration_driver_continue(self, finished):
  
          src_server = db_utils.create_share_server()
          dest_server = db_utils.create_share_server()
          share = db_utils.create_share(
              task_state=constants.TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS,
              id='share_id',
              share_server_id=src_server['id'],
              status=constants.STATUS_MIGRATING)
          share_cancelled = db_utils.create_share(
              task_state=constants.TASK_STATE_MIGRATION_CANCELLED)
          if finished:
              share_cancelled = share
          regular_instance = db_utils.create_share_instance(
              status=constants.STATUS_AVAILABLE,
              share_id='other_id')
          dest_instance = db_utils.create_share_instance(
              share_id='share_id',
              host='fake_host',
              share_server_id=dest_server['id'],
              status=constants.STATUS_MIGRATING_TO)
          src_instance = share.instance
          snapshot = db_utils.create_snapshot(share_id=share['id'])
          dest_snap_instance = db_utils.create_snapshot_instance(
              snapshot_id=snapshot['id'],
              share_instance_id=dest_instance['id'])
          migrating_snap_instance = db_utils.create_snapshot(
              status=constants.STATUS_MIGRATING,
              share_id=share['id'])
  
          snapshot_mappings = {snapshot.instance['id']: dest_snap_instance}
  
          self.mock_object(manager.LOG, 'warning')
          self.mock_object(self.share_manager.db,
                           'share_instances_get_all_by_host', mock.Mock(
                               return_value=[regular_instance, src_instance]))
          self.mock_object(self.share_manager.db, 'share_get',
                           mock.Mock(side_effect=[share, share_cancelled]))
          self.mock_object(api.API, 'get_migrating_instances',
                           mock.Mock(return_value=(
                               src_instance['id'], dest_instance['id'])))
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(return_value=dest_instance))
          self.mock_object(self.share_manager.db, 'share_server_get',
                           mock.Mock(side_effect=[src_server, dest_server]))
          self.mock_object(self.share_manager.driver, 'migration_continue',
                           mock.Mock(side_effect=[finished]))
          self.mock_object(self.share_manager.db, 'share_instance_update')
          self.mock_object(self.share_manager.db, 'share_update')
          self.mock_object(self.share_manager, '_migration_delete_instance')
  
          side_effect = [[dest_snap_instance], [snapshot.instance]]
          if isinstance(finished, Exception):
              side_effect.append([migrating_snap_instance])
  
          self.mock_object(
              self.share_manager.db,
              'share_snapshot_instance_get_all_with_filters',
              mock.Mock(side_effect=side_effect))
          self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_update')
  
          share_get_calls = [mock.call(self.context, 'share_id')]
          self.mock_object(self.share_manager, '_reset_read_only_access_rules')
  
          self.share_manager.migration_driver_continue(self.context)
  
          snapshot_instance_get_all_calls = [
              mock.call(self.context,
                        {'share_instance_ids': [dest_instance['id']]}),
              mock.call(self.context,
                        {'share_instance_ids': [src_instance['id']]})
          ]
  
          if isinstance(finished, Exception):
              self.share_manager.db.share_update.assert_called_once_with(
                  self.context, 'share_id',
                  {'task_state': constants.TASK_STATE_MIGRATION_ERROR})
              (self.share_manager.db.share_instance_update.
                  assert_called_once_with(
                      self.context, src_instance['id'],
                      {'status': constants.STATUS_AVAILABLE}))
              (self.share_manager._migration_delete_instance.
               assert_called_once_with(self.context, dest_instance['id']))
              (self.share_manager._reset_read_only_access_rules.
               assert_called_once_with(self.context, src_instance['id']))
              (self.share_manager.db.share_snapshot_instance_update.
               assert_called_once_with(
                   self.context, migrating_snap_instance['id'],
                   {'status': constants.STATUS_AVAILABLE}))
              snapshot_instance_get_all_calls.append(
                  mock.call(
                      self.context,
                      {'share_instance_ids': [src_instance['id']]}))
  
          else:
              if finished:
                  self.share_manager.db.share_update.assert_called_once_with(
                      self.context, 'share_id',
                      {'task_state':
                       constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE})
              else:
                  share_get_calls.append(mock.call(self.context, 'share_id'))
                  self.assertTrue(manager.LOG.warning.called)
  
          self.share_manager.db.share_instances_get_all_by_host(
              self.context, self.share_manager.host)
          self.share_manager.db.share_get.assert_has_calls(share_get_calls)
          api.API.get_migrating_instances.assert_called_once_with(share)
          self.share_manager.db.share_instance_get.assert_called_once_with(
              self.context, dest_instance['id'], with_share_data=True)
          self.share_manager.db.share_server_get.assert_has_calls([
              mock.call(self.context, src_server['id']),
              mock.call(self.context, dest_server['id']),
          ])
          self.share_manager.driver.migration_continue.assert_called_once_with(
              self.context, src_instance, dest_instance,
              [snapshot.instance], snapshot_mappings, src_server, dest_server)
  
          (self.share_manager.db.share_snapshot_instance_get_all_with_filters.
              assert_has_calls(snapshot_instance_get_all_calls))
  
      @ddt.data({'task_state': constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE,
                 'exc': None},
                {'task_state': constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE,
                 'exc': Exception('fake')},
                {'task_state': constants.TASK_STATE_DATA_COPYING_COMPLETED,
                 'exc': None},
                {'task_state': constants.TASK_STATE_DATA_COPYING_COMPLETED,
                 'exc': Exception('fake')})
      @ddt.unpack
      def test_migration_complete(self, task_state, exc):
  
          instance_1 = db_utils.create_share_instance(
              share_id='fake_id',
              status=constants.STATUS_MIGRATING,
              share_server_id='fake_server_id',
              share_type_id='fake_type_id')
          instance_2 = db_utils.create_share_instance(
              share_id='fake_id',
              status=constants.STATUS_MIGRATING_TO,
              share_server_id='fake_server_id',
              share_type_id='fake_type_id')
          share = db_utils.create_share(
              id='fake_id',
              instances=[instance_1, instance_2],
              task_state=task_state)
          model_type_update = {'create_share_from_snapshot_support': False}
          share_update = model_type_update
          share_update['task_state'] = constants.TASK_STATE_MIGRATION_SUCCESS
  
          # mocks
          self.mock_object(self.share_manager.db, 'share_get',
                           mock.Mock(return_value=share))
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(side_effect=[instance_1, instance_2]))
          self.mock_object(api.API, 'get_share_attributes_from_share_type',
                           mock.Mock(return_value=model_type_update))
          self.mock_object(share_types, 'get_share_type',
                           mock.Mock(return_value='fake_type'))
          self.mock_object(self.share_manager.db, 'share_update')
  
          if task_state == constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE:
              self.mock_object(
                  self.share_manager, '_migration_complete_driver',
                  mock.Mock(side_effect=exc))
          else:
              self.mock_object(
                  self.share_manager, '_migration_complete_host_assisted',
                  mock.Mock(side_effect=exc))
  
          if exc:
              snapshot = db_utils.create_snapshot(share_id=share['id'])
              snapshot_ins1 = db_utils.create_snapshot_instance(
                  snapshot_id=snapshot['id'],
                  share_instance_id=instance_1['id'],
                  status=constants.STATUS_MIGRATING,)
              snapshot_ins2 = db_utils.create_snapshot_instance(
                  snapshot_id=snapshot['id'],
                  share_instance_id=instance_2['id'],
                  status=constants.STATUS_MIGRATING_TO)
              self.mock_object(manager.LOG, 'exception')
              self.mock_object(self.share_manager.db, 'share_update')
              self.mock_object(self.share_manager.db, 'share_instance_update')
              self.mock_object(self.share_manager.db,
                               'share_snapshot_instance_update')
              self.mock_object(self.share_manager.db,
                               'share_snapshot_instance_get_all_with_filters',
                               mock.Mock(
                                   return_value=[snapshot_ins1, snapshot_ins2]))
  
              self.assertRaises(
                  exception.ShareMigrationFailed,
                  self.share_manager.migration_complete,
                  self.context, instance_1['id'], instance_2['id'])
  
          else:
              self.share_manager.migration_complete(
                  self.context, instance_1['id'], instance_2['id'])
  
          # asserts
          self.share_manager.db.share_get.assert_called_once_with(
              self.context, share['id'])
          self.share_manager.db.share_instance_get.assert_has_calls([
              mock.call(self.context, instance_1['id'], with_share_data=True),
              mock.call(self.context, instance_2['id'], with_share_data=True)])
  
          if task_state == constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE:
              (self.share_manager._migration_complete_driver.
               assert_called_once_with(
                   self.context, share, instance_1, instance_2))
          else:
              (self.share_manager._migration_complete_host_assisted.
               assert_called_once_with(
                   self.context, share, instance_1['id'], instance_2['id']))
          if exc:
              self.assertTrue(manager.LOG.exception.called)
              self.share_manager.db.share_update.assert_called_once_with(
                  self.context, share['id'],
                  {'task_state': constants.TASK_STATE_MIGRATION_ERROR})
              if task_state == constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE:
                  share_instance_update_calls = [
                      mock.call(self.context, instance_1['id'],
                                {'status': constants.STATUS_ERROR}),
                      mock.call(self.context, instance_2['id'],
                                {'status': constants.STATUS_ERROR})
                  ]
              else:
                  share_instance_update_calls = [
                      mock.call(self.context, instance_1['id'],
                                {'status': constants.STATUS_AVAILABLE}),
                  ]
              self.share_manager.db.share_instance_update.assert_has_calls(
                  share_instance_update_calls)
              if task_state == constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE:
                  (self.share_manager.db.share_snapshot_instance_update.
                   assert_has_calls([
                       mock.call(self.context, snapshot_ins1['id'],
                                 {'status': constants.STATUS_ERROR}),
                       mock.call(self.context, snapshot_ins2['id'],
                                 {'status': constants.STATUS_ERROR})]))
                  (self.share_manager.db.
                   share_snapshot_instance_get_all_with_filters.
                   assert_called_once_with(
                       self.context, {
                           'share_instance_ids': [instance_1['id'],
                                                  instance_2['id']]
                       }
                   ))
  
          else:
              (api.API.get_share_attributes_from_share_type.
               assert_called_once_with('fake_type'))
              share_types.get_share_type.assert_called_once_with(
                  self.context, 'fake_type_id')
              self.share_manager.db.share_update.assert_called_once_with(
                  self.context, share['id'], share_update)
  
      @ddt.data(constants.TASK_STATE_DATA_COPYING_ERROR,
                constants.TASK_STATE_DATA_COPYING_CANCELLED,
                constants.TASK_STATE_DATA_COPYING_COMPLETED,
                'other')
      def test__migration_complete_host_assisted_status(self, status):
  
          instance = db_utils.create_share_instance(
              share_id='fake_id',
              share_server_id='fake_server_id')
          new_instance = db_utils.create_share_instance(share_id='fake_id')
          share = db_utils.create_share(id='fake_id', task_state=status)
          helper = mock.Mock()
  
          # mocks
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(side_effect=[instance, new_instance]))
          self.mock_object(helper, 'cleanup_new_instance')
          self.mock_object(migration_api, 'ShareMigrationHelper',
                           mock.Mock(return_value=helper))
          self.mock_object(self.share_manager.db, 'share_instance_update')
          self.mock_object(self.share_manager.db, 'share_update')
          self.mock_object(self.share_manager, '_reset_read_only_access_rules')
  
          if status == constants.TASK_STATE_DATA_COPYING_COMPLETED:
              self.mock_object(helper, 'apply_new_access_rules',
                               mock.Mock(side_effect=Exception('fake')))
              self.mock_object(manager.LOG, 'exception')
  
          # run
          if status == constants.TASK_STATE_DATA_COPYING_CANCELLED:
              self.share_manager._migration_complete_host_assisted(
                  self.context, share, instance['id'], new_instance['id'])
          else:
              self.assertRaises(
                  exception.ShareMigrationFailed,
                  self.share_manager._migration_complete_host_assisted,
                  self.context, share, instance['id'], new_instance['id'])
  
          # asserts
          self.share_manager.db.share_instance_get.assert_has_calls([
              mock.call(self.context, instance['id'], with_share_data=True),
              mock.call(self.context, new_instance['id'], with_share_data=True)
          ])
  
          cancelled = not(status == constants.TASK_STATE_DATA_COPYING_CANCELLED)
          if status != 'other':
              helper.cleanup_new_instance.assert_called_once_with(new_instance)
              (self.share_manager._reset_read_only_access_rules.
               assert_called_once_with(self.context, instance['id'],
                                       helper=helper, supress_errors=cancelled))
          if status == constants.TASK_STATE_MIGRATION_CANCELLED:
              (self.share_manager.db.share_instance_update.
                  assert_called_once_with(
                      self.context, instance['id'],
                      {'status': constants.STATUS_AVAILABLE,
                       'progress': '100%'}))
              self.share_manager.db.share_update.assert_called_once_with(
                  self.context, share['id'],
                  {'task_state': constants.TASK_STATE_MIGRATION_CANCELLED})
          if status == constants.TASK_STATE_DATA_COPYING_COMPLETED:
              helper.apply_new_access_rules. assert_called_once_with(
                  new_instance, 'fake_id')
              self.assertTrue(manager.LOG.exception.called)
  
      @ddt.data({'mount_snapshot_support': True, 'snapshot_els': False},
                {'mount_snapshot_support': True, 'snapshot_els': True},
                {'mount_snapshot_support': False, 'snapshot_els': False},
                {'mount_snapshot_support': False, 'snapshot_els': True},)
      @ddt.unpack
      def test__migration_complete_driver(
              self, mount_snapshot_support, snapshot_els):
          fake_src_host = 'src_host'
          fake_dest_host = 'dest_host'
          fake_rules = 'fake_rules'
  
          src_server = db_utils.create_share_server()
          dest_server = db_utils.create_share_server()
          share_type = db_utils.create_share_type(
              extra_specs={'mount_snapshot_support': mount_snapshot_support})
          share = db_utils.create_share(
              share_server_id='fake_src_server_id',
              host=fake_src_host)
          dest_instance = db_utils.create_share_instance(
              share_id=share['id'],
              share_server_id='fake_dest_server_id',
              host=fake_dest_host,
              share_type_id=share_type['id'])
          src_instance = share.instance
          snapshot = db_utils.create_snapshot(share_id=share['id'])
          dest_snap_instance = db_utils.create_snapshot_instance(
              snapshot_id=snapshot['id'],
              share_instance_id=dest_instance['id'])
  
          snapshot_mappings = {snapshot.instance['id']: dest_snap_instance}
  
          model_update = {'fake_keys': 'fake_values'}
          if snapshot_els:
              el = {'path': 'fake_path', 'is_admin_only': False}
              model_update['export_locations'] = [el]
  
          fake_return_data = {
              'export_locations': 'fake_export_locations',
              'snapshot_updates': {dest_snap_instance['id']: model_update},
          }
  
          # mocks
          self.mock_object(self.share_manager.db, 'share_server_get', mock.Mock(
              side_effect=[src_server, dest_server]))
          self.mock_object(
              self.share_manager.db, 'share_access_get_all_for_instance',
              mock.Mock(return_value=fake_rules))
          self.mock_object(
              self.share_manager.db, 'share_export_locations_update')
          self.mock_object(self.share_manager.driver, 'migration_complete',
                           mock.Mock(return_value=fake_return_data))
          self.mock_object(
              self.share_manager.access_helper, '_check_needs_refresh',
              mock.Mock(return_value=True))
          self.mock_object(self.share_manager.db, 'share_instance_update')
          self.mock_object(self.share_manager.db, 'share_update')
          self.mock_object(self.share_manager, '_migration_delete_instance')
          self.mock_object(migration_api.ShareMigrationHelper,
                           'apply_new_access_rules')
          self.mock_object(
              self.share_manager.db,
              'share_snapshot_instance_get_all_with_filters',
              mock.Mock(side_effect=[[dest_snap_instance],
                                     [snapshot.instance]]))
          self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_update')
          el_create = self.mock_object(
              self.share_manager.db,
              'share_snapshot_instance_export_location_create')
  
          # run
          self.share_manager._migration_complete_driver(
              self.context, share, src_instance, dest_instance)
  
          # asserts
          self.share_manager.db.share_server_get.assert_has_calls([
              mock.call(self.context, 'fake_src_server_id'),
              mock.call(self.context, 'fake_dest_server_id')])
          (self.share_manager.db.share_export_locations_update.
           assert_called_once_with(self.context, dest_instance['id'],
                                   'fake_export_locations'))
          self.share_manager.driver.migration_complete.assert_called_once_with(
              self.context, src_instance, dest_instance, [snapshot.instance],
              snapshot_mappings, src_server, dest_server)
          (migration_api.ShareMigrationHelper.apply_new_access_rules.
           assert_called_once_with(dest_instance, share['id']))
          self.share_manager._migration_delete_instance.assert_called_once_with(
              self.context, src_instance['id'])
          self.share_manager.db.share_instance_update.assert_has_calls([
              mock.call(self.context, dest_instance['id'],
                        {'status': constants.STATUS_AVAILABLE,
                         'progress': '100%'}),
              mock.call(self.context, src_instance['id'],
                        {'status': constants.STATUS_INACTIVE})])
          self.share_manager.db.share_update.assert_called_once_with(
              self.context, dest_instance['share_id'],
              {'task_state': constants.TASK_STATE_MIGRATION_COMPLETING})
  
          (self.share_manager.db.share_snapshot_instance_get_all_with_filters.
           assert_has_calls([
               mock.call(self.context,
                         {'share_instance_ids': [dest_instance['id']]}),
               mock.call(self.context,
                         {'share_instance_ids': [src_instance['id']]})]))
  
          snap_data_update = (
              fake_return_data['snapshot_updates'][dest_snap_instance['id']])
          snap_data_update.update({
              'status': constants.STATUS_AVAILABLE,
              'progress': '100%',
          })
  
          (self.share_manager.db.share_snapshot_instance_update.
           assert_called_once_with(self.context, dest_snap_instance['id'],
                                   snap_data_update))
          if mount_snapshot_support and snapshot_els:
              el['share_snapshot_instance_id'] = dest_snap_instance['id']
              el_create.assert_called_once_with(self.context, el)
          else:
              el_create.assert_not_called()
  
      def test__migration_complete_host_assisted(self):
  
          instance = db_utils.create_share_instance(
              share_id='fake_id',
              share_server_id='fake_server_id')
          new_instance = db_utils.create_share_instance(share_id='fake_id')
          share = db_utils.create_share(
              id='fake_id',
              task_state=constants.TASK_STATE_DATA_COPYING_COMPLETED)
  
          # mocks
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(side_effect=[instance, new_instance]))
          self.mock_object(self.share_manager.db, 'share_instance_update')
          self.mock_object(self.share_manager.db, 'share_update')
          delete_mock = self.mock_object(migration_api.ShareMigrationHelper,
                                         'delete_instance_and_wait')
          self.mock_object(migration_api.ShareMigrationHelper,
                           'apply_new_access_rules')
  
          # run
          self.share_manager._migration_complete_host_assisted(
              self.context, share, instance['id'], new_instance['id'])
  
          # asserts
          self.share_manager.db.share_instance_get.assert_has_calls([
              mock.call(self.context, instance['id'], with_share_data=True),
              mock.call(self.context, new_instance['id'], with_share_data=True)
          ])
  
          self.share_manager.db.share_instance_update.assert_has_calls([
              mock.call(self.context, new_instance['id'],
                        {'status': constants.STATUS_AVAILABLE,
                         'progress': '100%'}),
              mock.call(self.context, instance['id'],
                        {'status': constants.STATUS_INACTIVE})
          ])
  
          self.share_manager.db.share_update.assert_called_once_with(
              self.context, share['id'],
              {'task_state': constants.TASK_STATE_MIGRATION_COMPLETING})
          (migration_api.ShareMigrationHelper.apply_new_access_rules.
              assert_called_once_with(new_instance, 'fake_id'))
          delete_mock.assert_called_once_with(instance)
  
      @ddt.data(constants.TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS,
                constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE,
                constants.TASK_STATE_DATA_COPYING_COMPLETED)
      def test_migration_cancel(self, task_state):
  
          dest_host = 'fake_host'
          server_1 = db_utils.create_share_server()
          server_2 = db_utils.create_share_server()
          share = db_utils.create_share(task_state=task_state)
  
          instance_1 = db_utils.create_share_instance(
              share_id=share['id'], share_server_id=server_1['id'])
          instance_2 = db_utils.create_share_instance(
              share_id=share['id'], share_server_id=server_2['id'],
              host=dest_host)
  
          helper = mock.Mock()
          self.mock_object(migration_api, 'ShareMigrationHelper',
                           mock.Mock(return_value=helper))
          self.mock_object(db, 'share_get', mock.Mock(return_value=share))
          self.mock_object(db, 'share_instance_get',
                           mock.Mock(side_effect=[instance_1, instance_2]))
          self.mock_object(db, 'share_update')
          self.mock_object(db, 'share_instance_update')
          self.mock_object(self.share_manager, '_migration_delete_instance')
          self.mock_object(self.share_manager,
                           '_restore_migrating_snapshots_status')
          self.mock_object(db, 'share_server_get',
                           mock.Mock(side_effect=[server_1, server_2]))
          self.mock_object(self.share_manager.driver, 'migration_cancel')
          self.mock_object(helper, 'cleanup_new_instance')
          self.mock_object(self.share_manager, '_reset_read_only_access_rules')
  
          self.share_manager.migration_cancel(
              self.context, instance_1['id'], instance_2['id'])
  
          share_instance_update_calls = []
  
          if task_state == constants.TASK_STATE_DATA_COPYING_COMPLETED:
              share_instance_update_calls.append(mock.call(
                  self.context, instance_2['id'],
                  {'status': constants.STATUS_INACTIVE}))
              (helper.cleanup_new_instance.assert_called_once_with(instance_2))
              (self.share_manager._reset_read_only_access_rules.
               assert_called_once_with(self.context, instance_1['id'],
                                       helper=helper, supress_errors=False))
  
          else:
              self.share_manager.driver.migration_cancel.assert_called_once_with(
                  self.context, instance_1, instance_2, [], {}, server_1,
                  server_2)
  
              (self.share_manager._migration_delete_instance.
               assert_called_once_with(self.context, instance_2['id']))
              (self.share_manager._restore_migrating_snapshots_status.
               assert_called_once_with(self.context, instance_1['id']))
  
          self.share_manager.db.share_get.assert_called_once_with(
              self.context, share['id'])
          self.share_manager.db.share_server_get.assert_has_calls([
              mock.call(self.context, server_1['id']),
              mock.call(self.context, server_2['id']),
          ])
          self.share_manager.db.share_instance_get.assert_has_calls([
              mock.call(self.context, instance_1['id'], with_share_data=True),
              mock.call(self.context, instance_2['id'], with_share_data=True)
          ])
          self.share_manager.db.share_update.assert_called_once_with(
              self.context, share['id'],
              {'task_state': constants.TASK_STATE_MIGRATION_CANCELLED})
  
          share_instance_update_calls.append(mock.call(
              self.context, instance_1['id'],
              {'status': constants.STATUS_AVAILABLE}))
  
          self.share_manager.db.share_instance_update.assert_has_calls(
              share_instance_update_calls)
  
      @ddt.data(True, False)
      def test__reset_read_only_access_rules(self, supress_errors):
  
          share = db_utils.create_share()
          server = db_utils.create_share_server()
          instance = db_utils.create_share_instance(
              share_id=share['id'],
              cast_rules_to_readonly=True,
              share_server_id=server['id'])
  
          # mocks
          self.mock_object(self.share_manager.db, 'share_server_get',
                           mock.Mock(return_value=server))
          self.mock_object(self.share_manager.db, 'share_instance_update')
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(return_value=instance))
          self.mock_object(migration_api.ShareMigrationHelper,
                           'cleanup_access_rules')
          self.mock_object(migration_api.ShareMigrationHelper,
                           'revert_access_rules')
  
          # run
          self.share_manager._reset_read_only_access_rules(
              self.context, instance['id'], supress_errors=supress_errors)
  
          # asserts
          self.share_manager.db.share_server_get.assert_called_once_with(
              self.context, server['id'])
          self.share_manager.db.share_instance_update.assert_called_once_with(
              self.context, instance['id'],
              {'cast_rules_to_readonly': False})
          self.share_manager.db.share_instance_get.assert_has_calls([
              mock.call(self.context, instance['id'], with_share_data=True),
              mock.call(self.context, instance['id'], with_share_data=True)])
          if supress_errors:
              (migration_api.ShareMigrationHelper.cleanup_access_rules.
               assert_called_once_with([instance], server, None))
          else:
              (migration_api.ShareMigrationHelper.revert_access_rules.
               assert_called_once_with([instance], server, None))
  
      def test__migration_delete_instance(self):
  
          share = db_utils.create_share(id='fake_id')
          instance = share.instance
          snapshot = db_utils.create_snapshot(share_id=share['id'])
          rules = [{'id': 'rule_id_1'}, {'id': 'rule_id_2'}]
  
          # mocks
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(return_value=instance))
          mock_get_access_rules_call = self.mock_object(
              self.share_manager.access_helper,
              'get_and_update_share_instance_access_rules',
              mock.Mock(return_value=rules))
          mock_delete_access_rules_call = self.mock_object(
              self.share_manager.access_helper,
              'delete_share_instance_access_rules')
          self.mock_object(self.share_manager.db, 'share_instance_delete')
          self.mock_object(self.share_manager.db, 'share_instance_access_delete')
          self.mock_object(self.share_manager, '_check_delete_share_server')
          self.mock_object(self.share_manager.db,
                           'share_snapshot_instance_delete')
          self.mock_object(self.share_manager.db,
                           'share_snapshot_instance_get_all_with_filters',
                           mock.Mock(return_value=[snapshot.instance]))
  
          # run
          self.share_manager._migration_delete_instance(
              self.context, instance['id'])
  
          # asserts
          self.share_manager.db.share_instance_get.assert_called_once_with(
              self.context, instance['id'], with_share_data=True)
          mock_get_access_rules_call.assert_called_once_with(
              self.context, share_instance_id=instance['id'])
          mock_delete_access_rules_call.assert_called_once_with(
              self.context, rules, instance['id'])
          self.share_manager.db.share_instance_delete.assert_called_once_with(
              self.context, instance['id'])
          self.share_manager._check_delete_share_server.assert_called_once_with(
              self.context, share_instance=instance)
          (self.share_manager.db.share_snapshot_instance_get_all_with_filters.
           assert_called_once_with(self.context,
                                   {'share_instance_ids': [instance['id']]}))
          (self.share_manager.db.share_snapshot_instance_delete.
           assert_called_once_with(self.context, snapshot.instance['id']))
  
      def test_migration_cancel_invalid(self):
  
          share = db_utils.create_share()
  
          self.mock_object(db, 'share_instance_get',
                           mock.Mock(return_value=share.instance))
          self.mock_object(db, 'share_get', mock.Mock(return_value=share))
  
          self.assertRaises(
              exception.InvalidShare, self.share_manager.migration_cancel,
              self.context, 'ins1_id', 'ins2_id')
  
      def test_migration_get_progress(self):
  
          expected = 'fake_progress'
          dest_host = 'fake_host'
          server_1 = db_utils.create_share_server()
          server_2 = db_utils.create_share_server()
          share = db_utils.create_share(
              task_state=constants.TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS,
              share_server_id=server_1['id'])
  
          instance_1 = db_utils.create_share_instance(
              share_id=share['id'], share_server_id=server_1['id'])
          instance_2 = db_utils.create_share_instance(
              share_id=share['id'], share_server_id=server_2['id'],
              host=dest_host)
  
          self.mock_object(db, 'share_get', mock.Mock(return_value=share))
          self.mock_object(db, 'share_instance_get',
                           mock.Mock(side_effect=[instance_1, instance_2]))
  
          self.mock_object(db, 'share_server_get',
                           mock.Mock(side_effect=[server_1, server_2]))
  
          self.mock_object(self.share_manager.driver, 'migration_get_progress',
                           mock.Mock(return_value=expected))
  
          result = self.share_manager.migration_get_progress(
              self.context, instance_1['id'], instance_2['id'])
  
          self.assertEqual(expected, result)
  
          (self.share_manager.driver.migration_get_progress.
              assert_called_once_with(
                  self.context, instance_1, instance_2, [], {}, server_1,
                  server_2))
  
          self.share_manager.db.share_get.assert_called_once_with(
              self.context, share['id'])
          self.share_manager.db.share_server_get.assert_has_calls([
              mock.call(self.context, server_1['id']),
              mock.call(self.context, server_2['id']),
          ])
          self.share_manager.db.share_instance_get.assert_has_calls([
              mock.call(self.context, instance_1['id'], with_share_data=True),
              mock.call(self.context, instance_2['id'], with_share_data=True)
          ])
  
      def test_migration_get_progress_invalid(self):
  
          share = db_utils.create_share()
  
          self.mock_object(db, 'share_instance_get',
                           mock.Mock(return_value=share.instance))
          self.mock_object(db, 'share_get', mock.Mock(return_value=share))
  
          self.assertRaises(
              exception.InvalidShare, self.share_manager.migration_get_progress,
              self.context, 'ins1_id', 'ins2_id')
  
      def test_provide_share_server(self):
  
          instance = db_utils.create_share_instance(share_id='fake_id',
                                                    share_group_id='sg_id')
          snapshot = db_utils.create_snapshot(with_share=True)
          group = db_utils.create_share_group()
          server = db_utils.create_share_server()
  
          # mocks
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(return_value=instance))
          self.mock_object(self.share_manager.db, 'share_snapshot_get',
                           mock.Mock(return_value=snapshot))
          self.mock_object(self.share_manager.db, 'share_group_get',
                           mock.Mock(return_value=group))
          self.mock_object(self.share_manager, '_provide_share_server_for_share',
                           mock.Mock(return_value=(server, instance)))
  
          # run
          result = self.share_manager.provide_share_server(
              self.context, 'ins_id', 'net_id', 'snap_id')
  
          # asserts
          self.assertEqual(server['id'], result)
          self.share_manager.db.share_instance_get.assert_called_once_with(
              self.context, 'ins_id', with_share_data=True)
          self.share_manager.db.share_snapshot_get.assert_called_once_with(
              self.context, 'snap_id')
          self.share_manager.db.share_group_get.assert_called_once_with(
              self.context, 'sg_id')
          (self.share_manager._provide_share_server_for_share.
           assert_called_once_with(self.context, 'net_id', instance, snapshot,
                                   group, create_on_backend=False))
  
      def test_create_share_server(self):
  
          server = db_utils.create_share_server()
          share = db_utils.create_share()
          fake_metadata = {
              'request_host': 'fake_host',
              'share_type_id': 'fake_share_type_id',
          }
  
          # mocks
          self.mock_object(self.share_manager.db, 'share_server_get',
                           mock.Mock(return_value=server))
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(return_value=share))
          self.mock_object(self.share_manager, '_create_share_server_in_backend')
          self.mock_object(self.share_manager, '_build_server_metadata',
                           mock.Mock(return_value=fake_metadata))
  
          # run
          self.share_manager.create_share_server(
              self.context, 'server_id', 'share_instance_id')
  
          # asserts
          self.share_manager.db.share_server_get.assert_called_once_with(
              self.context, 'server_id')
          self.share_manager.db.share_instance_get.assert_called_once_with(
              self.context, 'share_instance_id', with_share_data=True)
          (self.share_manager._create_share_server_in_backend.
           assert_called_once_with(self.context, server, fake_metadata))
  
      @ddt.data({'admin_network_api': mock.Mock(),
                 'driver_return': ('new_identifier', {'some_id': 'some_value'})},
                {'admin_network_api': None,
                 'driver_return': (None, None)})
      @ddt.unpack
      def test_manage_share_server(self, admin_network_api, driver_return):
          driver_opts = {}
          fake_share_server = fakes.fake_share_server_get()
          fake_list_network_info = [{}, {}]
          fake_list_empty_network_info = []
          identifier = 'fake_id'
          ss_data = {
              'name': 'fake_name',
              'ou': 'fake_ou',
              'domain': 'fake_domain',
              'server': 'fake_server',
              'dns_ip': 'fake_dns_ip',
              'user': 'fake_user',
              'type': 'FAKE',
              'password': 'fake_pass',
          }
          mock_manage_admin_network_allocations = mock.Mock()
          share_server = db_utils.create_share_server(**fake_share_server)
          security_service = db_utils.create_security_service(**ss_data)
          share_network = db_utils.create_share_network()
          share_net_subnet = db_utils.create_share_network_subnet(
              share_network_id=share_network['id'])
          db.share_network_add_security_service(context.get_admin_context(),
                                                share_network['id'],
                                                security_service['id'])
          share_network = db.share_network_get(context.get_admin_context(),
                                               share_network['id'])
          self.share_manager.driver._admin_network_api = admin_network_api
  
          mock_share_server_update = self.mock_object(
              db, 'share_server_update')
          mock_share_server_get = self.mock_object(
              db, 'share_server_get', mock.Mock(return_value=share_server))
          mock_share_network_get = self.mock_object(
              db, 'share_network_get', mock.Mock(return_value=share_network))
          mock_share_net_subnet_get = self.mock_object(
              db, 'share_network_subnet_get', mock.Mock(
                  return_value=share_net_subnet)
          )
          mock_network_allocations_get = self.mock_object(
              self.share_manager.driver, 'get_network_allocations_number',
              mock.Mock(return_value=1))
          mock_share_server_net_info = self.mock_object(
              self.share_manager.driver, 'get_share_server_network_info',
              mock.Mock(return_value=fake_list_network_info))
          mock_manage_network_allocations = self.mock_object(
              self.share_manager.driver.network_api,
              'manage_network_allocations',
              mock.Mock(return_value=fake_list_empty_network_info))
          mock_manage_server = self.mock_object(
              self.share_manager.driver, 'manage_server',
              mock.Mock(return_value=driver_return))
          mock_set_backend_details = self.mock_object(
              db, 'share_server_backend_details_set')
  
          ss_from_db = share_network['security_services'][0]
          ss_data_from_db = {
              'name': ss_from_db['name'],
              'ou': ss_from_db['ou'],
              'domain': ss_from_db['domain'],
              'server': ss_from_db['server'],
              'dns_ip': ss_from_db['dns_ip'],
              'user': ss_from_db['user'],
              'type': ss_from_db['type'],
              'password': ss_from_db['password'],
          }
  
          expected_backend_details = {
              'security_service_FAKE': jsonutils.dumps(ss_data_from_db),
          }
          if driver_return[1]:
              expected_backend_details.update(driver_return[1])
  
          if admin_network_api is not None:
              mock_manage_admin_network_allocations = self.mock_object(
                  self.share_manager.driver.admin_network_api,
                  'manage_network_allocations',
                  mock.Mock(return_value=fake_list_network_info))
  
          self.share_manager.manage_share_server(self.context,
                                                 fake_share_server['id'],
                                                 identifier,
                                                 driver_opts)
  
          mock_share_server_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_share_server['id']
          )
          mock_share_network_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              share_net_subnet['share_network_id']
          )
          mock_share_net_subnet_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              fake_share_server['share_network_subnet_id']
          )
          mock_network_allocations_get.assert_called_once_with()
          mock_share_server_net_info.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), share_server, identifier,
              driver_opts
          )
          mock_manage_network_allocations.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              fake_list_network_info, share_server, share_network,
              share_net_subnet
          )
          mock_manage_server.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), share_server, identifier,
              driver_opts
          )
          mock_share_server_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_share_server['id'],
              {'status': constants.STATUS_ACTIVE,
               'identifier': driver_return[0] or share_server['id']}
          )
          mock_set_backend_details.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), share_server['id'],
              expected_backend_details
          )
          if admin_network_api is not None:
              mock_manage_admin_network_allocations.assert_called_once_with(
                  utils.IsAMatcher(context.RequestContext),
                  fake_list_network_info, share_server
              )
  
      def test_manage_share_server_dhss_false(self):
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = False
          self.assertRaises(
              exception.ManageShareServerError,
              self.share_manager.manage_share_server,
              self.context, "fake_id", "foo", {})
  
      def test_manage_share_server_without_allocations(self):
  
          driver_opts = {}
          fake_share_server = fakes.fake_share_server_get()
          fake_list_empty_network_info = []
          identifier = 'fake_id'
          share_server = db_utils.create_share_server(**fake_share_server)
          share_network = db_utils.create_share_network()
          share_network_subnet = db_utils.create_share_network_subnet(
              share_network_id=share_network['id']
          )
          share_server['share_network_subnet_id'] = share_network_subnet['id']
          self.share_manager.driver._admin_network_api = mock.Mock()
  
          mock_share_server_get = self.mock_object(
              db, 'share_server_get', mock.Mock(return_value=share_server))
          mock_share_network_get = self.mock_object(
              db, 'share_network_get', mock.Mock(return_value=share_network))
          mock_share_net_subnet_get = self.mock_object(
              db, 'share_network_subnet_get', mock.Mock(
                  return_value=share_network_subnet))
          mock_network_allocations_get = self.mock_object(
              self.share_manager.driver, 'get_network_allocations_number',
              mock.Mock(return_value=1))
          mock_get_share_network_info = self.mock_object(
              self.share_manager.driver, 'get_share_server_network_info',
              mock.Mock(return_value=fake_list_empty_network_info))
  
          self.assertRaises(exception.ManageShareServerError,
                            self.share_manager.manage_share_server,
                            context=self.context,
                            share_server_id=fake_share_server['id'],
                            identifier=identifier,
                            driver_opts=driver_opts)
          mock_share_server_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_share_server['id']
          )
          mock_share_network_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              share_network_subnet['share_network_id']
          )
          mock_share_net_subnet_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              share_server['share_network_subnet_id']
          )
          mock_network_allocations_get.assert_called_once_with()
          mock_get_share_network_info.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), share_server, identifier,
              driver_opts
          )
  
      def test_manage_share_server_allocations_not_managed(self):
          driver_opts = {}
          fake_share_server = fakes.fake_share_server_get()
          fake_list_network_info = [{}, {}]
          identifier = 'fake_id'
          share_server = db_utils.create_share_server(**fake_share_server)
          share_network = db_utils.create_share_network()
          share_network_subnet = db_utils.create_share_network_subnet(
              share_network_id=share_network['id']
          )
          share_server['share_network_subnet_id'] = share_network_subnet['id']
          self.share_manager.driver._admin_network_api = mock.Mock()
  
          mock_share_server_get = self.mock_object(
              db, 'share_server_get', mock.Mock(return_value=share_server))
          mock_share_network_get = self.mock_object(
              db, 'share_network_get', mock.Mock(return_value=share_network))
          mock_share_net_subnet_get = self.mock_object(
              db, 'share_network_subnet_get', mock.Mock(
                  return_value=share_network_subnet))
          mock_network_allocations_get = self.mock_object(
              self.share_manager.driver, 'get_network_allocations_number',
              mock.Mock(return_value=1))
          mock_get_share_network_info = self.mock_object(
              self.share_manager.driver, 'get_share_server_network_info',
              mock.Mock(return_value=fake_list_network_info))
          mock_manage_admin_network_allocations = self.mock_object(
              self.share_manager.driver.admin_network_api,
              'manage_network_allocations',
              mock.Mock(return_value=fake_list_network_info))
          mock_manage_network_allocations = self.mock_object(
              self.share_manager.driver.network_api,
              'manage_network_allocations',
              mock.Mock(return_value=fake_list_network_info))
  
          self.assertRaises(exception.ManageShareServerError,
                            self.share_manager.manage_share_server,
                            context=self.context,
                            share_server_id=fake_share_server['id'],
                            identifier=identifier,
                            driver_opts=driver_opts)
          mock_share_server_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_share_server['id']
          )
          mock_share_network_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              share_network_subnet['share_network_id']
          )
          mock_share_net_subnet_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              share_server['share_network_subnet_id']
          )
          mock_network_allocations_get.assert_called_once_with()
          mock_get_share_network_info.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), share_server, identifier,
              driver_opts
          )
          mock_manage_admin_network_allocations.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              fake_list_network_info, share_server
          )
          mock_manage_network_allocations.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              fake_list_network_info, share_server, share_network,
              share_network_subnet
          )
  
      def test_manage_snapshot_driver_exception(self):
          CustomException = type('CustomException', (Exception,), {})
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = False
          self.mock_object(share_types,
                           'get_share_type_extra_specs',
                           mock.Mock(return_value="False"))
          mock_manage = self.mock_object(self.share_manager.driver,
                                         'manage_existing_snapshot',
                                         mock.Mock(side_effect=CustomException))
          share = db_utils.create_share()
          snapshot = db_utils.create_snapshot(share_id=share['id'])
          driver_options = {}
          mock_get = self.mock_object(self.share_manager.db,
                                      'share_snapshot_get',
                                      mock.Mock(return_value=snapshot))
  
          self.assertRaises(
              CustomException,
              self.share_manager.manage_snapshot,
              self.context, snapshot['id'], driver_options)
  
          mock_manage.assert_called_once_with(mock.ANY, driver_options)
          mock_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), snapshot['id'])
  
      def test_unmanage_share_server_no_allocations(self):
  
          fake_share_server = fakes.fake_share_server_get()
  
          ss_list = [
              {'name': 'fake_AD'},
              {'name': 'fake_LDAP'},
              {'name': 'fake_kerberos'}
          ]
  
          db_utils.create_share_server(**fake_share_server)
          self.mock_object(self.share_manager.driver, 'unmanage_server',
                           mock.Mock(side_effect=NotImplementedError()))
          self.mock_object(self.share_manager.db, 'share_server_delete')
  
          mock_network_allocations_number = self.mock_object(
              self.share_manager.driver, 'get_network_allocations_number',
              mock.Mock(return_value=0)
          )
          mock_admin_network_allocations_number = self.mock_object(
              self.share_manager.driver, 'get_admin_network_allocations_number',
              mock.Mock(return_value=0)
          )
  
          self.share_manager.unmanage_share_server(
              self.context, fake_share_server['id'], True)
  
          mock_network_allocations_number.assert_called_once_with()
          mock_admin_network_allocations_number.assert_called_once_with()
  
          self.share_manager.driver.unmanage_server.assert_called_once_with(
              fake_share_server['backend_details'], ss_list)
          self.share_manager.db.share_server_delete.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_share_server['id'])
  
      def test_unmanage_share_server_no_allocations_driver_not_implemented(self):
  
          fake_share_server = fakes.fake_share_server_get()
          fake_share_server['status'] = constants.STATUS_UNMANAGING
          ss_list = [
              {'name': 'fake_AD'},
              {'name': 'fake_LDAP'},
              {'name': 'fake_kerberos'}
          ]
          db_utils.create_share_server(**fake_share_server)
          self.mock_object(self.share_manager.driver, 'unmanage_server',
                           mock.Mock(side_effect=NotImplementedError()))
          self.mock_object(self.share_manager.db, 'share_server_update')
  
          self.share_manager.unmanage_share_server(
              self.context, fake_share_server['id'], False)
  
          self.share_manager.driver.unmanage_server.assert_called_once_with(
              fake_share_server['backend_details'], ss_list)
  
          self.share_manager.db.share_server_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_share_server['id'],
              {'status': constants.STATUS_UNMANAGE_ERROR})
  
      def test_unmanage_share_server_with_network_allocations(self):
  
          fake_share_server = fakes.fake_share_server_get()
          db_utils.create_share_server(**fake_share_server)
  
          mock_unmanage_network_allocations = self.mock_object(
              self.share_manager.driver.network_api,
              'unmanage_network_allocations'
          )
          mock_network_allocations_number = self.mock_object(
              self.share_manager.driver, 'get_network_allocations_number',
              mock.Mock(return_value=1)
          )
  
          self.share_manager.unmanage_share_server(
              self.context, fake_share_server['id'], True)
          mock_network_allocations_number.assert_called_once_with()
          mock_unmanage_network_allocations.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_share_server['id'])
  
      def test_unmanage_share_server_with_admin_network_allocations(self):
  
          fake_share_server = fakes.fake_share_server_get()
          db_utils.create_share_server(**fake_share_server)
  
          mock_admin_network_allocations_number = self.mock_object(
              self.share_manager.driver, 'get_admin_network_allocations_number',
              mock.Mock(return_value=1)
          )
          mock_network_allocations_number = self.mock_object(
              self.share_manager.driver, 'get_network_allocations_number',
              mock.Mock(return_value=0)
          )
  
          self.share_manager.driver._admin_network_api = mock.Mock()
          self.share_manager.unmanage_share_server(
              self.context, fake_share_server['id'], True)
  
          mock_admin_network_allocations_number.assert_called_once_with()
          mock_network_allocations_number.assert_called_once_with()
  
      def test_unmanage_share_server_error(self):
  
          fake_share_server = fakes.fake_share_server_get()
          db_utils.create_share_server(**fake_share_server)
  
          mock_network_allocations_number = self.mock_object(
              self.share_manager.driver, 'get_network_allocations_number',
              mock.Mock(return_value=1)
          )
          error = mock.Mock(
              side_effect=exception.ShareServerNotFound(share_server_id="fake"))
  
          mock_share_server_delete = self.mock_object(
              db, 'share_server_delete', error
          )
          mock_share_server_update = self.mock_object(
              db, 'share_server_update'
          )
          self.share_manager.driver._admin_network_api = mock.Mock()
  
          self.assertRaises(exception.ShareServerNotFound,
                            self.share_manager.unmanage_share_server,
                            self.context,
                            fake_share_server['id'],
                            True)
          mock_network_allocations_number.assert_called_once_with()
          mock_share_server_delete.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_share_server['id']
          )
          mock_share_server_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_share_server['id'],
              {'status': constants.STATUS_UNMANAGE_ERROR}
          )
  
      def test_unmanage_share_server_network_allocations_error(self):
  
          fake_share_server = fakes.fake_share_server_get()
          db_utils.create_share_server(**fake_share_server)
  
          mock_network_allocations_number = self.mock_object(
              self.share_manager.driver, 'get_network_allocations_number',
              mock.Mock(return_value=1)
          )
          error = mock.Mock(
              side_effect=exception.ShareNetworkNotFound(share_network_id="fake")
          )
          mock_unmanage_network_allocations = self.mock_object(
              self.share_manager.driver.network_api,
              'unmanage_network_allocations', error)
  
          mock_share_server_update = self.mock_object(
              db, 'share_server_update'
          )
          self.share_manager.driver._admin_network_api = mock.Mock()
  
          self.assertRaises(exception.ShareNetworkNotFound,
                            self.share_manager.unmanage_share_server,
                            self.context,
                            fake_share_server['id'],
                            True)
  
          mock_network_allocations_number.assert_called_once_with()
          mock_unmanage_network_allocations.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_share_server['id']
          )
          mock_share_server_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_share_server['id'],
              {'status': constants.STATUS_UNMANAGE_ERROR}
          )
  
      def test_unmanage_share_server_admin_network_allocations_error(self):
  
          fake_share_server = fakes.fake_share_server_get()
          db_utils.create_share_server(**fake_share_server)
          self.share_manager.driver._admin_network_api = mock.Mock()
  
          mock_network_allocations_number = self.mock_object(
              self.share_manager.driver, 'get_network_allocations_number',
              mock.Mock(return_value=0)
          )
          mock_admin_network_allocations_number = self.mock_object(
              self.share_manager.driver, 'get_admin_network_allocations_number',
              mock.Mock(return_value=1)
          )
          error = mock.Mock(
              side_effect=exception.ShareNetworkNotFound(share_network_id="fake")
          )
          mock_unmanage_admin_network_allocations = self.mock_object(
              self.share_manager.driver._admin_network_api,
              'unmanage_network_allocations', error
          )
          mock_unmanage_network_allocations = self.mock_object(
              self.share_manager.driver.network_api,
              'unmanage_network_allocations', error)
  
          mock_share_server_update = self.mock_object(
              db, 'share_server_update'
          )
  
          self.assertRaises(exception.ShareNetworkNotFound,
                            self.share_manager.unmanage_share_server,
                            self.context,
                            fake_share_server['id'],
                            True)
          mock_network_allocations_number.assert_called_once_with()
          mock_admin_network_allocations_number.assert_called_once_with()
          mock_unmanage_network_allocations.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_share_server['id']
          )
          mock_unmanage_admin_network_allocations.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_share_server['id']
          )
          mock_share_server_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), fake_share_server['id'],
              {'status': constants.STATUS_UNMANAGE_ERROR}
          )
  
      @ddt.data({'dhss': True, 'driver_data': {'size': 1},
                 'mount_snapshot_support': False},
                {'dhss': True, 'driver_data': {'size': 2, 'name': 'fake'},
                 'mount_snapshot_support': False},
                {'dhss': False, 'driver_data': {'size': 3},
                 'mount_snapshot_support': False},
                {'dhss': False, 'driver_data': {'size': 3, 'export_locations': [
                    {'path': '/path1', 'is_admin_only': True},
                    {'path': '/path2', 'is_admin_only': False}
                ]}, 'mount_snapshot_support': False},
                {'dhss': False, 'driver_data': {'size': 3, 'export_locations': [
                    {'path': '/path1', 'is_admin_only': True},
                    {'path': '/path2', 'is_admin_only': False}
                ]}, 'mount_snapshot_support': True})
      @ddt.unpack
      def test_manage_snapshot_valid_snapshot(
              self, driver_data, mount_snapshot_support, dhss):
          mock_get_share_server = self.mock_object(self.share_manager,
                                                   '_get_share_server',
                                                   mock.Mock(return_value=None))
          self.mock_object(self.share_manager.db, 'share_snapshot_update')
          self.mock_object(self.share_manager, 'driver')
          self.mock_object(quota.QUOTAS, 'reserve', mock.Mock())
          self.share_manager.driver.driver_handles_share_servers = dhss
  
          if dhss:
              mock_manage = self.mock_object(
                  self.share_manager.driver,
                  "manage_existing_snapshot_with_server",
                  mock.Mock(return_value=driver_data))
          else:
              mock_manage = self.mock_object(
                  self.share_manager.driver,
                  "manage_existing_snapshot",
                  mock.Mock(return_value=driver_data))
          size = driver_data['size']
          export_locations = driver_data.get('export_locations')
          share = db_utils.create_share(
              size=size,
              mount_snapshot_support=mount_snapshot_support)
          snapshot = db_utils.create_snapshot(share_id=share['id'], size=size)
          snapshot_id = snapshot['id']
          driver_options = {}
          mock_get = self.mock_object(self.share_manager.db,
                                      'share_snapshot_get',
                                      mock.Mock(return_value=snapshot))
          mock_export_update = self.mock_object(
              self.share_manager.db,
              'share_snapshot_instance_export_location_create')
  
          self.share_manager.manage_snapshot(self.context, snapshot_id,
                                             driver_options)
  
          if dhss:
              mock_manage.assert_called_once_with(mock.ANY, driver_options, None)
          else:
              mock_manage.assert_called_once_with(mock.ANY, driver_options)
          valid_snapshot_data = {
              'status': constants.STATUS_AVAILABLE}
          valid_snapshot_data.update(driver_data)
          self.share_manager.db.share_snapshot_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              snapshot_id, valid_snapshot_data)
          if dhss:
              mock_get_share_server.assert_called_once_with(
                  utils.IsAMatcher(context.RequestContext), snapshot['share'])
          mock_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), snapshot_id)
          if mount_snapshot_support and export_locations:
              snap_ins_id = snapshot.instance['id']
              for i in range(0, 2):
                  export_locations[i]['share_snapshot_instance_id'] = snap_ins_id
              mock_export_update.assert_has_calls([
                  mock.call(utils.IsAMatcher(context.RequestContext),
                            export_locations[0]),
                  mock.call(utils.IsAMatcher(context.RequestContext),
                            export_locations[1]),
              ])
          else:
              mock_export_update.assert_not_called()
  
      def test_unmanage_snapshot_invalid_share(self):
          manager.CONF.unmanage_remove_access_rules = False
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = False
          mock_unmanage = mock.Mock(
              side_effect=exception.UnmanageInvalidShareSnapshot(reason="fake"))
          self.mock_object(self.share_manager.driver, "unmanage_snapshot",
                           mock_unmanage)
          mock_get_share_server = self.mock_object(
              self.share_manager,
              '_get_share_server',
              mock.Mock(return_value=None))
          self.mock_object(self.share_manager.db, 'share_snapshot_update')
          share = db_utils.create_share()
          snapshot = db_utils.create_snapshot(share_id=share['id'])
          mock_get = self.mock_object(self.share_manager.db,
                                      'share_snapshot_get',
                                      mock.Mock(return_value=snapshot))
  
          self.share_manager.unmanage_snapshot(self.context, snapshot['id'])
  
          self.share_manager.db.share_snapshot_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), snapshot['id'],
              {'status': constants.STATUS_UNMANAGE_ERROR})
          self.share_manager.driver.unmanage_snapshot.assert_called_once_with(
              mock.ANY)
          mock_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), snapshot['id'])
          mock_get_share_server.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), snapshot['share'])
  
      @ddt.data({'dhss': False, 'quota_error': False},
                {'dhss': True, 'quota_error': False},
                {'dhss': False, 'quota_error': True},
                {'dhss': True, 'quota_error': True})
      @ddt.unpack
      def test_unmanage_snapshot_valid_snapshot(self, dhss, quota_error):
          if quota_error:
              self.mock_object(quota.QUOTAS, 'reserve', mock.Mock(
                  side_effect=exception.ManilaException(message='error')))
          manager.CONF.unmanage_remove_access_rules = True
          mock_log_warning = self.mock_object(manager.LOG, 'warning')
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = dhss
          mock_update_access = self.mock_object(
              self.share_manager.snapshot_access_helper, "update_access_rules")
          if dhss:
              mock_unmanage = self.mock_object(
                  self.share_manager.driver, "unmanage_snapshot_with_server")
          else:
              mock_unmanage = self.mock_object(
                  self.share_manager.driver, "unmanage_snapshot")
          mock_get_share_server = self.mock_object(
              self.share_manager,
              '_get_share_server',
              mock.Mock(return_value=None))
          mock_snapshot_instance_destroy_call = self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_delete')
          share = db_utils.create_share()
          snapshot = db_utils.create_snapshot(share_id=share['id'])
          mock_get = self.mock_object(self.share_manager.db,
                                      'share_snapshot_get',
                                      mock.Mock(return_value=snapshot))
          mock_snap_ins_get = self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_get',
              mock.Mock(return_value=snapshot.instance))
  
          self.share_manager.unmanage_snapshot(self.context, snapshot['id'])
  
          if dhss:
              mock_unmanage.assert_called_once_with(snapshot.instance, None)
          else:
              mock_unmanage.assert_called_once_with(snapshot.instance)
          mock_update_access.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), snapshot.instance['id'],
              delete_all_rules=True, share_server=None)
          mock_snapshot_instance_destroy_call.assert_called_once_with(
              mock.ANY, snapshot['instance']['id'])
          mock_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), snapshot['id'])
          mock_get_share_server.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), snapshot['share'])
          mock_snap_ins_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), snapshot.instance['id'],
              with_share_data=True)
          if quota_error:
              self.assertTrue(mock_log_warning.called)
  
      @ddt.data(True, False)
      def test_revert_to_snapshot(self, has_replicas):
  
          reservations = 'fake_reservations'
          share_id = 'fake_share_id'
          snapshot_id = 'fake_snapshot_id'
          snapshot_instance_id = 'fake_snapshot_instance_id'
          share_instance_id = 'fake_share_instance_id'
          share_instance = fakes.fake_share_instance(
              id=share_instance_id, share_id=share_id)
          share = fakes.fake_share(
              id=share_id, instance=share_instance,
              project_id='fake_project', user_id='fake_user', size=2,
              has_replicas=has_replicas)
          snapshot_instance = fakes.fake_snapshot_instance(
              id=snapshot_instance_id, share_id=share_instance_id, share=share,
              name='fake_snapshot', share_instance=share_instance,
              share_instance_id=share_instance_id)
          snapshot = fakes.fake_snapshot(
              id=snapshot_id, share_id=share_id, share=share,
              instance=snapshot_instance, project_id='fake_project',
              user_id='fake_user', size=1)
          share_access_rules = ['fake_share_access_rule']
          snapshot_access_rules = ['fake_snapshot_access_rule']
  
          mock_share_snapshot_get = self.mock_object(
              self.share_manager.db, 'share_snapshot_get',
              mock.Mock(return_value=snapshot))
          mock_share_access_get = self.mock_object(
              self.share_manager.access_helper,
              'get_share_instance_access_rules',
              mock.Mock(return_value=share_access_rules))
          mock_snapshot_access_get = self.mock_object(
              self.share_manager.snapshot_access_helper,
              'get_snapshot_instance_access_rules',
              mock.Mock(return_value=snapshot_access_rules))
          mock_revert_to_snapshot = self.mock_object(
              self.share_manager, '_revert_to_snapshot')
          mock_revert_to_replicated_snapshot = self.mock_object(
              self.share_manager, '_revert_to_replicated_snapshot')
  
          self.share_manager.revert_to_snapshot(self.context, snapshot_id,
                                                reservations)
  
          mock_share_snapshot_get.assert_called_once_with(mock.ANY, snapshot_id)
          mock_share_access_get.assert_called_once_with(
              mock.ANY, filters={'state': constants.STATUS_ACTIVE},
              share_instance_id=share_instance_id)
          mock_snapshot_access_get.assert_called_once_with(
              mock.ANY, snapshot_instance_id)
  
          if not has_replicas:
              mock_revert_to_snapshot.assert_called_once_with(
                  mock.ANY, share, snapshot, reservations, share_access_rules,
                  snapshot_access_rules)
              self.assertFalse(mock_revert_to_replicated_snapshot.called)
          else:
              self.assertFalse(mock_revert_to_snapshot.called)
              mock_revert_to_replicated_snapshot.assert_called_once_with(
                  mock.ANY, share, snapshot, reservations, share_access_rules,
                  snapshot_access_rules, share_id=share_id)
  
      @ddt.data(None, 'fake_reservations')
      def test__revert_to_snapshot(self, reservations):
  
          mock_quotas_rollback = self.mock_object(quota.QUOTAS, 'rollback')
          mock_quotas_commit = self.mock_object(quota.QUOTAS, 'commit')
          self.mock_object(
              self.share_manager, '_get_share_server',
              mock.Mock(return_value=None))
          mock_driver = self.mock_object(self.share_manager, 'driver')
  
          share_id = 'fake_share_id'
          share = fakes.fake_share(
              id=share_id, instance={'id': 'fake_instance_id',
                                     'share_type_id': 'fake_share_type_id'},
              project_id='fake_project', user_id='fake_user', size=2)
          snapshot_instance = fakes.fake_snapshot_instance(
              share_id=share_id, share=share, name='fake_snapshot',
              share_instance=share['instance'])
          snapshot = fakes.fake_snapshot(
              id='fake_snapshot_id', share_id=share_id, share=share,
              instance=snapshot_instance, project_id='fake_project',
              user_id='fake_user', size=1)
          share_access_rules = []
          snapshot_access_rules = []
  
          self.mock_object(
              self.share_manager.db, 'share_snapshot_get',
              mock.Mock(return_value=snapshot))
          self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_get',
              mock.Mock(return_value=snapshot_instance))
          mock_share_update = self.mock_object(
              self.share_manager.db, 'share_update')
          mock_share_snapshot_update = self.mock_object(
              self.share_manager.db, 'share_snapshot_update')
  
          self.share_manager._revert_to_snapshot(self.context, share, snapshot,
                                                 reservations,
                                                 share_access_rules,
                                                 snapshot_access_rules)
  
          mock_driver.revert_to_snapshot.assert_called_once_with(
              mock.ANY,
              self._get_snapshot_instance_dict(
                  snapshot_instance, share, snapshot=snapshot),
              share_access_rules, snapshot_access_rules,
              share_server=None)
  
          self.assertFalse(mock_quotas_rollback.called)
          if reservations:
              mock_quotas_commit.assert_called_once_with(
                  mock.ANY, reservations, project_id='fake_project',
                  user_id='fake_user',
                  share_type_id=(
                      snapshot_instance['share_instance']['share_type_id']))
          else:
              self.assertFalse(mock_quotas_commit.called)
  
          mock_share_update.assert_called_once_with(
              mock.ANY, share_id,
              {'status': constants.STATUS_AVAILABLE, 'size': snapshot['size']})
          mock_share_snapshot_update.assert_called_once_with(
              mock.ANY, 'fake_snapshot_id',
              {'status': constants.STATUS_AVAILABLE})
  
      @ddt.data(None, 'fake_reservations')
      def test__revert_to_snapshot_driver_exception(self, reservations):
  
          mock_quotas_rollback = self.mock_object(quota.QUOTAS, 'rollback')
          mock_quotas_commit = self.mock_object(quota.QUOTAS, 'commit')
          self.mock_object(
              self.share_manager, '_get_share_server',
              mock.Mock(return_value=None))
          mock_driver = self.mock_object(self.share_manager, 'driver')
          mock_driver.revert_to_snapshot.side_effect = exception.ManilaException
  
          share_id = 'fake_share_id'
          share = fakes.fake_share(
              id=share_id, instance={'id': 'fake_instance_id',
                                     'share_type_id': 'fake_share_type_id'},
              project_id='fake_project', user_id='fake_user', size=2)
          snapshot_instance = fakes.fake_snapshot_instance(
              share_id=share_id, share=share, name='fake_snapshot',
              share_instance=share['instance'])
          snapshot = fakes.fake_snapshot(
              id='fake_snapshot_id', share_id=share_id, share=share,
              instance=snapshot_instance, project_id='fake_project',
              user_id='fake_user', size=1)
          share_access_rules = []
          snapshot_access_rules = []
  
          self.mock_object(
              self.share_manager.db, 'share_snapshot_get',
              mock.Mock(return_value=snapshot))
          self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_get',
              mock.Mock(return_value=snapshot_instance))
          mock_share_update = self.mock_object(
              self.share_manager.db, 'share_update')
          mock_share_snapshot_update = self.mock_object(
              self.share_manager.db, 'share_snapshot_update')
  
          self.assertRaises(exception.ManilaException,
                            self.share_manager._revert_to_snapshot,
                            self.context,
                            share,
                            snapshot,
                            reservations,
                            share_access_rules,
                            snapshot_access_rules)
  
          mock_driver.revert_to_snapshot.assert_called_once_with(
              mock.ANY,
              self._get_snapshot_instance_dict(
                  snapshot_instance, share, snapshot=snapshot),
              share_access_rules,
              snapshot_access_rules,
              share_server=None)
  
          self.assertFalse(mock_quotas_commit.called)
          if reservations:
              mock_quotas_rollback.assert_called_once_with(
                  mock.ANY, reservations, project_id='fake_project',
                  user_id='fake_user',
                  share_type_id=(
                      snapshot_instance['share_instance']['share_type_id']))
          else:
              self.assertFalse(mock_quotas_rollback.called)
  
          mock_share_update.assert_called_once_with(
              mock.ANY, share_id,
              {'status': constants.STATUS_REVERTING_ERROR})
          mock_share_snapshot_update.assert_called_once_with(
              mock.ANY, 'fake_snapshot_id',
              {'status': constants.STATUS_AVAILABLE})
  
      def test_unmanage_snapshot_update_access_rule_exception(self):
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = False
          share = db_utils.create_share()
          snapshot = db_utils.create_snapshot(share_id=share['id'])
          manager.CONF.unmanage_remove_access_rules = True
  
          mock_get = self.mock_object(
              self.share_manager.db, 'share_snapshot_get',
              mock.Mock(return_value=snapshot))
  
          mock_get_share_server = self.mock_object(
              self.share_manager, '_get_share_server',
              mock.Mock(return_value=None))
  
          self.mock_object(self.share_manager.snapshot_access_helper,
                           'update_access_rules',
                           mock.Mock(side_effect=Exception))
          mock_log_exception = self.mock_object(manager.LOG, 'exception')
  
          mock_update = self.mock_object(self.share_manager.db,
                                         'share_snapshot_update')
  
          self.share_manager.unmanage_snapshot(self.context, snapshot['id'])
  
          self.assertTrue(mock_log_exception.called)
          mock_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), snapshot['id'])
          mock_get_share_server.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), snapshot['share'])
          mock_update.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext), snapshot['id'],
              {'status': constants.STATUS_UNMANAGE_ERROR})
  
      def test_snapshot_update_access(self):
          snapshot = fakes.fake_snapshot(create_instance=True)
          snapshot_instance = fakes.fake_snapshot_instance(
              base_snapshot=snapshot)
  
          mock_instance_get = self.mock_object(
              db, 'share_snapshot_instance_get',
              mock.Mock(return_value=snapshot_instance))
  
          mock_get_share_server = self.mock_object(self.share_manager,
                                                   '_get_share_server',
                                                   mock.Mock(return_value=None))
  
          mock_update_access = self.mock_object(
              self.share_manager.snapshot_access_helper, 'update_access_rules')
  
          self.share_manager.snapshot_update_access(self.context,
                                                    snapshot_instance['id'])
  
          mock_instance_get.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              snapshot_instance['id'], with_share_data=True)
          mock_get_share_server.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              snapshot_instance['share_instance'])
          mock_update_access.assert_called_once_with(
              utils.IsAMatcher(context.RequestContext),
              snapshot_instance['id'], share_server=None)
  
      def _setup_crud_replicated_snapshot_data(self):
          snapshot = fakes.fake_snapshot(create_instance=True)
          snapshot_instance = fakes.fake_snapshot_instance(
              base_snapshot=snapshot)
          snapshot_instances = [snapshot['instance'], snapshot_instance]
          replicas = [fake_replica(), fake_replica()]
          return snapshot, snapshot_instances, replicas
  
      def test_create_replicated_snapshot_driver_exception(self):
          snapshot, snapshot_instances, replicas = (
              self._setup_crud_replicated_snapshot_data()
          )
          self.mock_object(
              db, 'share_snapshot_get', mock.Mock(return_value=snapshot))
          self.mock_object(self.share_manager, '_get_share_server')
          self.mock_object(db, 'share_snapshot_instance_get_all_with_filters',
                           mock.Mock(return_value=snapshot_instances))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=replicas))
          self.mock_object(
              self.share_manager.driver, 'create_replicated_snapshot',
              mock.Mock(side_effect=exception.ManilaException))
          mock_db_update_call = self.mock_object(
              db, 'share_snapshot_instance_update')
  
          self.assertRaises(exception.ManilaException,
                            self.share_manager.create_replicated_snapshot,
                            self.context, snapshot['id'], share_id='fake_share')
          mock_db_update_call.assert_has_calls([
              mock.call(
                  self.context, snapshot['instance']['id'],
                  {'status': constants.STATUS_ERROR}),
              mock.call(
                  self.context, snapshot_instances[1]['id'],
                  {'status': constants.STATUS_ERROR}),
          ])
  
      @ddt.data(None, [])
      def test_create_replicated_snapshot_driver_updates_nothing(self, retval):
          snapshot, snapshot_instances, replicas = (
              self._setup_crud_replicated_snapshot_data()
          )
          self.mock_object(
              db, 'share_snapshot_get', mock.Mock(return_value=snapshot))
          self.mock_object(self.share_manager, '_get_share_server')
          self.mock_object(db, 'share_snapshot_instance_get_all_with_filters',
                           mock.Mock(return_value=snapshot_instances))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=replicas))
          self.mock_object(
              self.share_manager.driver, 'create_replicated_snapshot',
              mock.Mock(return_value=retval))
          mock_db_update_call = self.mock_object(
              db, 'share_snapshot_instance_update')
  
          return_value = self.share_manager.create_replicated_snapshot(
              self.context, snapshot['id'], share_id='fake_share')
  
          self.assertIsNone(return_value)
          self.assertFalse(mock_db_update_call.called)
  
      def test_create_replicated_snapshot_driver_updates_snapshot(self):
          snapshot, snapshot_instances, replicas = (
              self._setup_crud_replicated_snapshot_data()
          )
          snapshot_dict = {
              'status': constants.STATUS_AVAILABLE,
              'provider_location': 'spinners_end',
              'progress': '100%',
              'id': snapshot['instance']['id'],
          }
          self.mock_object(
              db, 'share_snapshot_get', mock.Mock(return_value=snapshot))
          self.mock_object(self.share_manager, '_get_share_server')
          self.mock_object(db, 'share_snapshot_instance_get_all_with_filters',
                           mock.Mock(return_value=snapshot_instances))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=replicas))
          self.mock_object(
              self.share_manager.driver, 'create_replicated_snapshot',
              mock.Mock(return_value=[snapshot_dict]))
          mock_db_update_call = self.mock_object(
              db, 'share_snapshot_instance_update')
  
          return_value = self.share_manager.create_replicated_snapshot(
              self.context, snapshot['id'], share_id='fake_share')
  
          self.assertIsNone(return_value)
          mock_db_update_call.assert_called_once_with(
              self.context, snapshot['instance']['id'], snapshot_dict)
  
      @ddt.data(None, 'fake_reservations')
      def test_revert_to_replicated_snapshot(self, reservations):
  
          share_id = 'id1'
          mock_quotas_rollback = self.mock_object(quota.QUOTAS, 'rollback')
          mock_quotas_commit = self.mock_object(quota.QUOTAS, 'commit')
          share = fakes.fake_share(
              id=share_id, project_id='fake_project', user_id='fake_user')
          snapshot = fakes.fake_snapshot(
              create_instance=True, share=share, size=1)
          snapshot_instance = fakes.fake_snapshot_instance(
              base_snapshot=snapshot)
          snapshot_instances = [snapshot['instance'], snapshot_instance]
          active_replica = fake_replica(
              id='rid1', share_id=share_id, host=self.share_manager.host,
              replica_state=constants.REPLICA_STATE_ACTIVE, as_primitive=False)
          replica = fake_replica(
              id='rid2', share_id=share_id, host='secondary',
              replica_state=constants.REPLICA_STATE_IN_SYNC, as_primitive=False)
          replicas = [active_replica, replica]
          share_access_rules = []
          snapshot_access_rules = []
          self.mock_object(
              db, 'share_snapshot_get', mock.Mock(return_value=snapshot))
          self.mock_object(
              self.share_manager, '_get_share_server',
              mock.Mock(return_value=None))
          self.mock_object(
              db, 'share_replicas_get_all_by_share',
              mock.Mock(return_value=replicas))
          self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(side_effect=[snapshot_instances,
                                     [snapshot_instances[0]]]))
          mock_driver = self.mock_object(self.share_manager, 'driver')
          mock_share_update = self.mock_object(
              self.share_manager.db, 'share_update')
          mock_share_replica_update = self.mock_object(
              self.share_manager.db, 'share_replica_update')
          mock_share_snapshot_instance_update = self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_update')
  
          self.share_manager._revert_to_replicated_snapshot(
              self.context, share, snapshot, reservations, share_access_rules,
              snapshot_access_rules, share_id=share_id)
  
          self.assertTrue(mock_driver.revert_to_replicated_snapshot.called)
          self.assertFalse(mock_quotas_rollback.called)
          if reservations:
              mock_quotas_commit.assert_called_once_with(
                  mock.ANY, reservations, project_id='fake_project',
                  user_id='fake_user', share_type_id=None)
          else:
              self.assertFalse(mock_quotas_commit.called)
  
          mock_share_update.assert_called_once_with(
              mock.ANY, share_id, {'size': snapshot['size']})
          mock_share_replica_update.assert_called_once_with(
              mock.ANY, active_replica['id'],
              {'status': constants.STATUS_AVAILABLE})
          mock_share_snapshot_instance_update.assert_called_once_with(
              mock.ANY, snapshot['instance']['id'],
              {'status': constants.STATUS_AVAILABLE})
  
      @ddt.data(None, 'fake_reservations')
      def test_revert_to_replicated_snapshot_driver_exception(
              self, reservations):
  
          mock_quotas_rollback = self.mock_object(quota.QUOTAS, 'rollback')
          mock_quotas_commit = self.mock_object(quota.QUOTAS, 'commit')
          share_id = 'id1'
          share = fakes.fake_share(
              id=share_id, project_id='fake_project', user_id='fake_user')
          snapshot = fakes.fake_snapshot(
              create_instance=True, share=share, size=1)
          snapshot_instance = fakes.fake_snapshot_instance(
              base_snapshot=snapshot)
          snapshot_instances = [snapshot['instance'], snapshot_instance]
          active_replica = fake_replica(
              id='rid1', share_id=share_id, host=self.share_manager.host,
              replica_state=constants.REPLICA_STATE_ACTIVE, as_primitive=False,
              share_type_id='fake_share_type_id')
          replica = fake_replica(
              id='rid2', share_id=share_id, host='secondary',
              replica_state=constants.REPLICA_STATE_IN_SYNC, as_primitive=False,
              share_type_id='fake_share_type_id')
          replicas = [active_replica, replica]
          share_access_rules = []
          snapshot_access_rules = []
          self.mock_object(
              db, 'share_snapshot_get', mock.Mock(return_value=snapshot))
          self.mock_object(
              self.share_manager, '_get_share_server',
              mock.Mock(return_value=None))
          self.mock_object(
              db, 'share_replicas_get_all_by_share',
              mock.Mock(return_value=replicas))
          self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(side_effect=[snapshot_instances,
                                     [snapshot_instances[0]]]))
          mock_driver = self.mock_object(self.share_manager, 'driver')
          mock_driver.revert_to_replicated_snapshot.side_effect = (
              exception.ManilaException)
          mock_share_update = self.mock_object(
              self.share_manager.db, 'share_update')
          mock_share_replica_update = self.mock_object(
              self.share_manager.db, 'share_replica_update')
          mock_share_snapshot_instance_update = self.mock_object(
              self.share_manager.db, 'share_snapshot_instance_update')
  
          self.assertRaises(exception.ManilaException,
                            self.share_manager._revert_to_replicated_snapshot,
                            self.context,
                            share,
                            snapshot,
                            reservations,
                            share_access_rules,
                            snapshot_access_rules,
                            share_id=share_id)
  
          self.assertTrue(mock_driver.revert_to_replicated_snapshot.called)
          self.assertFalse(mock_quotas_commit.called)
          if reservations:
              mock_quotas_rollback.assert_called_once_with(
                  mock.ANY, reservations, project_id='fake_project',
                  user_id='fake_user', share_type_id=replica['share_type_id'])
          else:
              self.assertFalse(mock_quotas_rollback.called)
  
          self.assertFalse(mock_share_update.called)
          mock_share_replica_update.assert_called_once_with(
              mock.ANY, active_replica['id'],
              {'status': constants.STATUS_REVERTING_ERROR})
          mock_share_snapshot_instance_update.assert_called_once_with(
              mock.ANY, snapshot['instance']['id'],
              {'status': constants.STATUS_AVAILABLE})
  
      def delete_replicated_snapshot_driver_exception(self):
          snapshot, snapshot_instances, replicas = (
              self._setup_crud_replicated_snapshot_data()
          )
          self.mock_object(
              db, 'share_snapshot_get', mock.Mock(return_value=snapshot))
          self.mock_object(self.share_manager, '_get_share_server')
          self.mock_object(db, 'share_snapshot_instance_get_all_with_filters',
                           mock.Mock(return_value=snapshot_instances))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=replicas))
          self.mock_object(
              self.share_manager.driver, 'delete_replicated_snapshot',
              mock.Mock(side_effect=exception.ManilaException))
          mock_db_update_call = self.mock_object(
              db, 'share_snapshot_instance_update')
          mock_db_delete_call = self.mock_object(
              db, 'share_snapshot_instance_delete')
  
          self.assertRaises(exception.ManilaException,
                            self.share_manager.delete_replicated_snapshot,
                            self.context, snapshot['id'], share_id='fake_share')
          mock_db_update_call.assert_has_calls([
              mock.call(
                  self.context, snapshot['instance']['id'],
                  {'status': constants.STATUS_ERROR_DELETING}),
              mock.call(
                  self.context, snapshot_instances[1]['id'],
                  {'status': constants.STATUS_ERROR_DELETING}),
          ])
          self.assertFalse(mock_db_delete_call.called)
  
      def delete_replicated_snapshot_driver_exception_ignored_with_force(self):
          snapshot, snapshot_instances, replicas = (
              self._setup_crud_replicated_snapshot_data()
          )
          self.mock_object(
              db, 'share_snapshot_get', mock.Mock(return_value=snapshot))
          self.mock_object(self.share_manager, '_get_share_server')
          self.mock_object(db, 'share_snapshot_instance_get_all_with_filters',
                           mock.Mock(return_value=snapshot_instances))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=replicas))
          self.mock_object(
              self.share_manager.driver, 'delete_replicated_snapshot',
              mock.Mock(side_effect=exception.ManilaException))
          mock_db_update_call = self.mock_object(
              db, 'share_snapshot_instance_update')
          mock_db_delete_call = self.mock_object(
              db, 'share_snapshot_instance_delete')
  
          retval = self.share_manager.delete_replicated_snapshot(
              self.context, snapshot['id'], share_id='fake_share')
  
          self.assertIsNone(retval)
          mock_db_delete_call.assert_has_calls([
              mock.call(
                  self.context, snapshot['instance']['id']),
              mock.call(
                  self.context, snapshot_instances[1]['id']),
          ])
          self.assertFalse(mock_db_update_call.called)
  
      @ddt.data(None, [])
      def delete_replicated_snapshot_driver_updates_nothing(self, retval):
          snapshot, snapshot_instances, replicas = (
              self._setup_crud_replicated_snapshot_data()
          )
          self.mock_object(
              db, 'share_snapshot_get', mock.Mock(return_value=snapshot))
          self.mock_object(self.share_manager, '_get_share_server')
          self.mock_object(db, 'share_snapshot_instance_get_all_with_filters',
                           mock.Mock(return_value=snapshot_instances))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=replicas))
          self.mock_object(
              self.share_manager.driver, 'delete_replicated_snapshot',
              mock.Mock(return_value=retval))
          mock_db_update_call = self.mock_object(
              db, 'share_snapshot_instance_update')
          mock_db_delete_call = self.mock_object(
              db, 'share_snapshot_instance_delete')
  
          return_value = self.share_manager.delete_replicated_snapshot(
              self.context, snapshot['id'], share_id='fake_share')
  
          self.assertIsNone(return_value)
          self.assertFalse(mock_db_delete_call.called)
          self.assertFalse(mock_db_update_call.called)
  
      def delete_replicated_snapshot_driver_deletes_snapshots(self):
          snapshot, snapshot_instances, replicas = (
              self._setup_crud_replicated_snapshot_data()
          )
          retval = [{
              'status': constants.STATUS_DELETED,
              'id': snapshot['instance']['id'],
          }]
          self.mock_object(
              db, 'share_snapshot_get', mock.Mock(return_value=snapshot))
          self.mock_object(self.share_manager, '_get_share_server')
          self.mock_object(db, 'share_snapshot_instance_get_all_with_filters',
                           mock.Mock(return_value=snapshot_instances))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=replicas))
          self.mock_object(
              self.share_manager.driver, 'delete_replicated_snapshot',
              mock.Mock(return_value=retval))
          mock_db_update_call = self.mock_object(
              db, 'share_snapshot_instance_update')
          mock_db_delete_call = self.mock_object(
              db, 'share_snapshot_instance_delete')
  
          return_value = self.share_manager.delete_replicated_snapshot(
              self.context, snapshot['id'], share_id='fake_share')
  
          self.assertIsNone(return_value)
          mock_db_delete_call.assert_called_once_with(
              self.context, snapshot['instance']['id'])
          self.assertFalse(mock_db_update_call.called)
  
      @ddt.data(True, False)
      def delete_replicated_snapshot_drv_del_and_updates_snapshots(self, force):
          snapshot, snapshot_instances, replicas = (
              self._setup_crud_replicated_snapshot_data()
          )
          updated_instance_details = {
              'status': constants.STATUS_ERROR,
              'id': snapshot_instances[1]['id'],
              'provider_location': 'azkaban',
          }
          retval = [
              {
                  'status': constants.STATUS_DELETED,
                  'id': snapshot['instance']['id'],
              },
          ]
          retval.append(updated_instance_details)
          self.mock_object(
              db, 'share_snapshot_get', mock.Mock(return_value=snapshot))
          self.mock_object(self.share_manager, '_get_share_server')
          self.mock_object(db, 'share_snapshot_instance_get_all_with_filters',
                           mock.Mock(return_value=snapshot_instances))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=replicas))
          self.mock_object(
              self.share_manager.driver, 'delete_replicated_snapshot',
              mock.Mock(return_value=retval))
          mock_db_update_call = self.mock_object(
              db, 'share_snapshot_instance_update')
          mock_db_delete_call = self.mock_object(
              db, 'share_snapshot_instance_delete')
  
          return_value = self.share_manager.delete_replicated_snapshot(
              self.context, snapshot['id'], share_id='fake_share', force=force)
  
          self.assertIsNone(return_value)
          if force:
              self.assertEqual(2, mock_db_delete_call.call_count)
              self.assertFalse(mock_db_update_call.called)
          else:
              mock_db_delete_call.assert_called_once_with(
                  self.context, snapshot['instance']['id'])
              mock_db_update_call.assert_called_once_with(
                  self.context, snapshot_instances[1]['id'],
                  updated_instance_details)
  
      def test_periodic_share_replica_snapshot_update(self):
          mock_debug_log = self.mock_object(manager.LOG, 'debug')
          replicas = 3 * [
              fake_replica(host='malfoy@manor#_pool0',
                           replica_state=constants.REPLICA_STATE_IN_SYNC)
          ]
          replicas.append(fake_replica(replica_state=constants.STATUS_ACTIVE))
          snapshot = fakes.fake_snapshot(create_instance=True,
                                         status=constants.STATUS_DELETING)
          snapshot_instances = 3 * [
              fakes.fake_snapshot_instance(base_snapshot=snapshot)
          ]
          self.mock_object(
              db, 'share_replicas_get_all', mock.Mock(return_value=replicas))
          self.mock_object(db, 'share_snapshot_instance_get_all_with_filters',
                           mock.Mock(return_value=snapshot_instances))
          mock_snapshot_update_call = self.mock_object(
              self.share_manager, '_update_replica_snapshot')
  
          retval = self.share_manager.periodic_share_replica_snapshot_update(
              self.context)
  
          self.assertIsNone(retval)
          self.assertEqual(1, mock_debug_log.call_count)
          self.assertEqual(0, mock_snapshot_update_call.call_count)
  
      @ddt.data(True, False)
      def test_periodic_share_replica_snapshot_update_nothing_to_update(
              self, has_instances):
          mock_debug_log = self.mock_object(manager.LOG, 'debug')
          replicas = 3 * [
              fake_replica(host='malfoy@manor#_pool0',
                           replica_state=constants.REPLICA_STATE_IN_SYNC)
          ]
          replicas.append(fake_replica(replica_state=constants.STATUS_ACTIVE))
          snapshot = fakes.fake_snapshot(create_instance=True,
                                         status=constants.STATUS_DELETING)
          snapshot_instances = 3 * [
              fakes.fake_snapshot_instance(base_snapshot=snapshot)
          ]
          self.mock_object(db, 'share_replicas_get_all',
                           mock.Mock(side_effect=[[], replicas]))
          self.mock_object(db, 'share_snapshot_instance_get_all_with_filters',
                           mock.Mock(side_effect=[snapshot_instances, []]))
          mock_snapshot_update_call = self.mock_object(
              self.share_manager, '_update_replica_snapshot')
  
          retval = self.share_manager.periodic_share_replica_snapshot_update(
              self.context)
  
          self.assertIsNone(retval)
          self.assertEqual(1, mock_debug_log.call_count)
          self.assertEqual(0, mock_snapshot_update_call.call_count)
  
      def test__update_replica_snapshot_replica_deleted_from_database(self):
          replica_not_found = exception.ShareReplicaNotFound(replica_id='xyzzy')
          self.mock_object(db, 'share_replica_get', mock.Mock(
              side_effect=replica_not_found))
          mock_db_delete_call = self.mock_object(
              db, 'share_snapshot_instance_delete')
          mock_db_update_call = self.mock_object(
              db, 'share_snapshot_instance_update')
          mock_driver_update_call = self.mock_object(
              self.share_manager.driver, 'update_replicated_snapshot')
          snaphot_instance = fakes.fake_snapshot_instance()
  
          retval = self.share_manager._update_replica_snapshot(
              self.context, snaphot_instance)
  
          self.assertIsNone(retval)
          mock_db_delete_call.assert_called_once_with(
              self.context, snaphot_instance['id'])
          self.assertFalse(mock_driver_update_call.called)
          self.assertFalse(mock_db_update_call.called)
  
      def test__update_replica_snapshot_both_deleted_from_database(self):
          replica_not_found = exception.ShareReplicaNotFound(replica_id='xyzzy')
          instance_not_found = exception.ShareSnapshotInstanceNotFound(
              instance_id='spoon!')
          self.mock_object(db, 'share_replica_get', mock.Mock(
              side_effect=replica_not_found))
          mock_db_delete_call = self.mock_object(
              db, 'share_snapshot_instance_delete', mock.Mock(
                  side_effect=instance_not_found))
          mock_db_update_call = self.mock_object(
              db, 'share_snapshot_instance_update')
          mock_driver_update_call = self.mock_object(
              self.share_manager.driver, 'update_replicated_snapshot')
          snapshot_instance = fakes.fake_snapshot_instance()
  
          retval = self.share_manager._update_replica_snapshot(
              self.context, snapshot_instance)
  
          self.assertIsNone(retval)
          mock_db_delete_call.assert_called_once_with(
              self.context, snapshot_instance['id'])
          self.assertFalse(mock_driver_update_call.called)
          self.assertFalse(mock_db_update_call.called)
  
      def test__update_replica_snapshot_driver_raises_Not_Found_exception(self):
          mock_debug_log = self.mock_object(manager.LOG, 'debug')
          replica = fake_replica()
          snapshot_instance = fakes.fake_snapshot_instance(
              status=constants.STATUS_DELETING)
          self.mock_object(
              db, 'share_replica_get', mock.Mock(return_value=replica))
          self.mock_object(db, 'share_snapshot_instance_get',
                           mock.Mock(return_value=snapshot_instance))
          self.mock_object(db, 'share_snapshot_instance_get',
                           mock.Mock(return_value=snapshot_instance))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica]))
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=None))
          self.mock_object(
              self.share_manager.driver, 'update_replicated_snapshot',
              mock.Mock(
                  side_effect=exception.SnapshotResourceNotFound(name='abc')))
          mock_db_delete_call = self.mock_object(
              db, 'share_snapshot_instance_delete')
          mock_db_update_call = self.mock_object(
              db, 'share_snapshot_instance_update')
  
          retval = self.share_manager._update_replica_snapshot(
              self.context, snapshot_instance, replica_snapshots=None)
  
          self.assertIsNone(retval)
          self.assertEqual(1, mock_debug_log.call_count)
          mock_db_delete_call.assert_called_once_with(
              self.context, snapshot_instance['id'])
          self.assertFalse(mock_db_update_call.called)
  
      @ddt.data(exception.NotFound, exception.ManilaException)
      def test__update_replica_snapshot_driver_raises_other_exception(self, exc):
          mock_debug_log = self.mock_object(manager.LOG, 'debug')
          mock_info_log = self.mock_object(manager.LOG, 'info')
          mock_exception_log = self.mock_object(manager.LOG, 'exception')
          replica = fake_replica()
          snapshot_instance = fakes.fake_snapshot_instance(
              status=constants.STATUS_CREATING)
          self.mock_object(
              db, 'share_replica_get', mock.Mock(return_value=replica))
          self.mock_object(db, 'share_snapshot_instance_get',
                           mock.Mock(return_value=snapshot_instance))
          self.mock_object(db, 'share_snapshot_instance_get',
                           mock.Mock(return_value=snapshot_instance))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica]))
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=None))
          self.mock_object(self.share_manager.driver,
                           'update_replicated_snapshot',
                           mock.Mock(side_effect=exc))
          mock_db_delete_call = self.mock_object(
              db, 'share_snapshot_instance_delete')
          mock_db_update_call = self.mock_object(
              db, 'share_snapshot_instance_update')
  
          retval = self.share_manager._update_replica_snapshot(
              self.context, snapshot_instance)
  
          self.assertIsNone(retval)
          self.assertEqual(1, mock_exception_log.call_count)
          self.assertEqual(1, mock_debug_log.call_count)
          self.assertFalse(mock_info_log.called)
          mock_db_update_call.assert_called_once_with(
              self.context, snapshot_instance['id'], {'status': 'error'})
          self.assertFalse(mock_db_delete_call.called)
  
      @ddt.data(True, False)
      def test__update_replica_snapshot_driver_updates_replica(self, update):
          replica = fake_replica()
          snapshot_instance = fakes.fake_snapshot_instance()
          driver_update = {}
          if update:
              driver_update = {
                  'id': snapshot_instance['id'],
                  'provider_location': 'knockturn_alley',
                  'status': constants.STATUS_AVAILABLE,
              }
          mock_debug_log = self.mock_object(manager.LOG, 'debug')
          mock_info_log = self.mock_object(manager.LOG, 'info')
          self.mock_object(
              db, 'share_replica_get', mock.Mock(return_value=replica))
          self.mock_object(db, 'share_snapshot_instance_get',
                           mock.Mock(return_value=snapshot_instance))
          self.mock_object(db, 'share_snapshot_instance_get',
                           mock.Mock(return_value=snapshot_instance))
          self.mock_object(db, 'share_replicas_get_all_by_share',
                           mock.Mock(return_value=[replica]))
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value=None))
          self.mock_object(self.share_manager.driver,
                           'update_replicated_snapshot',
                           mock.Mock(return_value=driver_update))
          mock_db_delete_call = self.mock_object(
              db, 'share_snapshot_instance_delete')
          mock_db_update_call = self.mock_object(
              db, 'share_snapshot_instance_update')
  
          retval = self.share_manager._update_replica_snapshot(
              self.context, snapshot_instance, replica_snapshots=None)
  
          driver_update['progress'] = '100%'
          self.assertIsNone(retval)
          self.assertEqual(1, mock_debug_log.call_count)
          self.assertFalse(mock_info_log.called)
          if update:
              mock_db_update_call.assert_called_once_with(
                  self.context, snapshot_instance['id'], driver_update)
          else:
              self.assertFalse(mock_db_update_call.called)
          self.assertFalse(mock_db_delete_call.called)
  
      def test_update_access(self):
          share_server = fakes.fake_share_server_get()
          kwargs = {'share_server_id': share_server['id']}
          share_instance = fakes.fake_share_instance(**kwargs)
          self.mock_object(self.share_manager, '_get_share_server',
                           mock.Mock(return_value='fake_share_server'))
          self.mock_object(self.share_manager, '_get_share_instance',
                           mock.Mock(return_value=share_instance))
          self.mock_object(self.share_manager.db, 'share_server_get',
                           mock.Mock(return_value=share_server))
          access_rules_update_method = self.mock_object(
              self.share_manager.access_helper, 'update_access_rules')
  
          retval = self.share_manager.update_access(
              self.context, share_instance['id'])
  
          self.assertIsNone(retval)
          access_rules_update_method.assert_called_once_with(
              self.context, share_instance['id'],
              share_server=share_server)
  
      @mock.patch('manila.tests.fake_notifier.FakeNotifier._notify')
      def test_update_share_usage_size(self, mock_notify):
          instances = self._setup_init_mocks(setup_access_rules=False)
          update_shares = [{'id': 'fake_id', 'used_size': '3',
                            'gathered_at': 'fake'}]
          mock_notify.assert_not_called()
  
          manager = self.share_manager
          self.mock_object(manager, 'driver')
          self.mock_object(manager.db, 'share_instances_get_all_by_host',
                           mock.Mock(return_value=instances))
          self.mock_object(manager.db, 'share_instance_get',
                           mock.Mock(side_effect=instances))
          mock_driver_call = self.mock_object(
              manager.driver, 'update_share_usage_size',
              mock.Mock(return_value=update_shares))
          self.share_manager.update_share_usage_size(self.context)
          self.assert_notify_called(mock_notify,
                                    (['INFO', 'share.consumed.size'], ))
          mock_driver_call.assert_called_once_with(
              self.context, instances)
  
      @mock.patch('manila.tests.fake_notifier.FakeNotifier._notify')
      def test_update_share_usage_size_fail(self, mock_notify):
          instances = self._setup_init_mocks(setup_access_rules=False)
          mock_notify.assert_not_called()
  
          self.mock_object(self.share_manager, 'driver')
          self.mock_object(self.share_manager.db,
                           'share_instances_get_all_by_host',
                           mock.Mock(return_value=instances))
          self.mock_object(self.share_manager.db, 'share_instance_get',
                           mock.Mock(side_effect=instances))
          self.mock_object(
              self.share_manager.driver, 'update_share_usage_size',
              mock.Mock(side_effect=exception.ProcessExecutionError))
          mock_log_exception = self.mock_object(manager.LOG, 'exception')
          self.share_manager.update_share_usage_size(self.context)
          self.assertTrue(mock_log_exception.called)
  
      def test_periodic_share_status_update(self):
          instances = self._setup_init_mocks(setup_access_rules=False)
          instances_creating_from_snap = [
              x for x in instances
              if x['status'] == constants.STATUS_CREATING_FROM_SNAPSHOT
          ]
          self.mock_object(self.share_manager, 'driver')
          self.mock_object(self.share_manager.db,
                           'share_instances_get_all_by_host',
                           mock.Mock(return_value=instances_creating_from_snap))
          mock_update_share_status = self.mock_object(
              self.share_manager, '_update_share_status')
          instances_dict = [
              self.share_manager._get_share_instance_dict(self.context, si)
              for si in instances_creating_from_snap]
  
          self.share_manager.periodic_share_status_update(self.context)
          mock_update_share_status.assert_has_calls([
              mock.call(self.context, share_instance)
              for share_instance in instances_dict
          ])
  
      def test__update_share_status(self):
          instances = self._setup_init_mocks(setup_access_rules=False)
          fake_export_locations = ['fake/path/1', 'fake/path']
          instance_model_update = {
              'status': constants.STATUS_AVAILABLE,
              'export_locations': fake_export_locations
          }
          expected_si_update_info = {
              'status': constants.STATUS_AVAILABLE,
              'progress': '100%'
          }
          driver_get_status = self.mock_object(
              self.share_manager.driver, 'get_share_status',
              mock.Mock(return_value=instance_model_update))
          db_si_update = self.mock_object(self.share_manager.db,
                                          'share_instance_update')
          db_el_update = self.mock_object(self.share_manager.db,
                                          'share_export_locations_update')
  
          in_progress_instances = [x for x in instances
                                   if x['status'] ==
                                   constants.STATUS_CREATING_FROM_SNAPSHOT]
          instance = self.share_manager.db.share_instance_get(
              self.context, in_progress_instances[0]['id'], with_share_data=True)
          self.share_manager._update_share_status(self.context, instance)
  
          driver_get_status.assert_called_once_with(instance, None)
          db_si_update.assert_called_once_with(self.context, instance['id'],
                                               expected_si_update_info)
          db_el_update.assert_called_once_with(self.context, instance['id'],
                                               fake_export_locations)
  
      @ddt.data(mock.Mock(return_value={'status': constants.STATUS_ERROR}),
                mock.Mock(side_effect=exception.ShareBackendException))
      def test__update_share_status_share_with_error_or_exception(self,
                                                                  driver_error):
          instances = self._setup_init_mocks(setup_access_rules=False)
          expected_si_update_info = {
              'status': constants.STATUS_ERROR,
              'progress': None,
          }
          driver_get_status = self.mock_object(
              self.share_manager.driver, 'get_share_status', driver_error)
          db_si_update = self.mock_object(self.share_manager.db,
                                          'share_instance_update')
  
          in_progress_instances = [x for x in instances
                                   if x['status'] ==
                                   constants.STATUS_CREATING_FROM_SNAPSHOT]
          instance = self.share_manager.db.share_instance_get(
              self.context, in_progress_instances[0]['id'], with_share_data=True)
  
          self.share_manager._update_share_status(self.context, instance)
          driver_get_status.assert_called_once_with(instance, None)
          db_si_update.assert_called_once_with(self.context, instance['id'],
                                               expected_si_update_info)
          self.share_manager.message_api.create.assert_called_once_with(
              self.context,
              message_field.Action.UPDATE,
              instance['project_id'],
              resource_type=message_field.Resource.SHARE,
              resource_id=instance['share_id'],
              detail=message_field.Detail.DRIVER_FAILED_CREATING_FROM_SNAP)
  
      def test__build_server_metadata(self):
          share = {'host': 'host', 'share_type_id': 'id'}
          expected_metadata = {'request_host': 'host', 'share_type_id': 'id'}
  
          metadata = self.share_manager._build_server_metadata(
              share['host'], share['share_type_id'])
  
          self.assertDictEqual(expected_metadata, metadata)
  
      @ddt.data(
          {
              'compatible': False,
              'writable': True,
              'nondisruptive': True,
              'preserve_snapshots': True,
          },
          {
              'compatible': True,
              'writable': False,
              'nondisruptive': True,
              'preserve_snapshots': True,
          },
          {
              'compatible': True,
              'writable': True,
              'nondisruptive': False,
              'preserve_snapshots': True,
          },
          {
              'compatible': True,
              'writable': True,
              'nondisruptive': True,
              'preserve_snapshots': False,
          },
          {
              'compatible': True,
              'writable': True,
              'nondisruptive': True,
              'preserve_snapshots': False,
              'not_preserve_with_instances': True
          },
      )
      @ddt.unpack
      def test__validate_check_compatibility_result(
              self, compatible, writable, nondisruptive,
              preserve_snapshots, not_preserve_with_instances=False):
          fake_share_network = db_utils.create_share_network()
          fake_share_server = db_utils.create_share_server()
          fake_share_server_dest = db_utils.create_share_server()
          share_instances = []
          snapshot_instances = [
              db_utils.create_snapshot(
                  with_share=True, status='available')['instance']]
  
          driver_compatibility = {
              'compatible': compatible,
              'writable': writable,
              'preserve_snapshots': preserve_snapshots,
              'nondisruptive': nondisruptive,
              'share_network_id': fake_share_network['id'],
              'migration_cancel': False,
              'migration_get_progress': False
          }
          specified_writable = True if not writable else writable
          specified_nondisruptive = True if not nondisruptive else nondisruptive
          specified_preserve_snapshots = (True if not preserve_snapshots else
                                          preserve_snapshots)
          if not preserve_snapshots and not_preserve_with_instances:
              specified_preserve_snapshots = False
  
          self.assertRaises(
              exception.ShareServerMigrationFailed,
              self.share_manager._validate_check_compatibility_result,
              self.context,
              fake_share_server['id'],
              share_instances,
              snapshot_instances,
              driver_compatibility,
              fake_share_server_dest['host'],
              specified_nondisruptive,
              specified_writable,
              specified_preserve_snapshots,
              resource_type='share server'
          )
  
      @ddt.data(
          {
              'kwargs': {'share_instance_ids': ['fakeid1']},
              'resource_type': 'share_instance'
          },
          {
              'kwargs': {'snapshot_instance_ids': ['fakeid1']},
              'resource_type': 'snapshot_instance'
          },
          {
              'kwargs': {
                  'snapshot_instance_ids': ['fakeid1'],
                  'task_state': constants.TASK_STATE_MIGRATION_STARTING},
              'resource_type': 'snapshot_instance'
          },
      )
      @ddt.unpack
      def test__update_resource_status(self, kwargs, resource_type):
          if resource_type == 'share_instance':
              mock_db_instances_status_update = self.mock_object(
                  db, 'share_instances_status_update')
          else:
              mock_db_instances_status_update = self.mock_object(
                  db, 'share_snapshot_instances_status_update')
  
          kwargs_relationship = {
              'share_instance': 'share_instance_ids',
              'snapshot_instance': 'snapshot_instance_ids'
          }
          resource_ids_key = kwargs_relationship.get(resource_type)
          resource_ids = kwargs.get(resource_ids_key)
          fields = {'status': constants.STATUS_AVAILABLE}
          if kwargs.get('task_state'):
              fields['task_state'] = kwargs['task_state']
  
          self.share_manager._update_resource_status(
              self.context, constants.STATUS_AVAILABLE, **kwargs)
  
          mock_db_instances_status_update.assert_called_once_with(
              self.context, resource_ids, fields)
  
      def _get_share_server_start_update_calls(
              self, source_share_server, dest_share_server, driver_failed=False):
          migration_in_progress_call = mock.call(
              self.context, dest_share_server['id'],
              {
                  'status': constants.STATUS_SERVER_MIGRATING_TO,
                  'task_state': constants.TASK_STATE_MIGRATION_IN_PROGRESS,
                  'source_share_server_id': source_share_server['id']
              }
          )
          driver_migration_starting_src_call = mock.call(
              self.context, source_share_server['id'],
              {'task_state': constants.TASK_STATE_MIGRATION_DRIVER_STARTING}
          )
          driver_migration_starting_dest_call = mock.call(
              self.context, dest_share_server['id'],
              {'task_state': constants.TASK_STATE_MIGRATION_DRIVER_STARTING}
          )
          driver_migration_src_call = mock.call(
              self.context, source_share_server['id'],
              {'task_state': constants.TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS}
          )
          driver_migration_dest_call = mock.call(
              self.context, dest_share_server['id'],
              {'task_state': constants.TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS}
          )
          driver_migration_dest_error = mock.call(
              self.context, dest_share_server['id'],
              {
                  'task_state': constants.TASK_STATE_MIGRATION_ERROR,
                  'status': constants.STATUS_ERROR
              }
          )
          mock_calls = [
              migration_in_progress_call, driver_migration_starting_src_call,
              driver_migration_starting_dest_call]
          if driver_failed:
              mock_calls.append(driver_migration_dest_error)
          else:
              mock_calls.append(driver_migration_src_call)
              mock_calls.append(driver_migration_dest_call)
          return mock_calls
  
      def _setup_server_migration_start_mocks(
              self, fake_share_instances, fake_snap_instances, fake_old_network,
              fake_new_network, fake_service, fake_request_spec,
              fake_driver_result, fake_new_share_server):
          self.mock_object(db, 'share_instances_get_all_by_share_server',
                           mock.Mock(return_value=fake_share_instances))
          self.mock_object(db, 'share_snapshot_instance_get_all_with_filters',
                           mock.Mock(return_value=fake_snap_instances))
          self.mock_object(db, 'share_network_get',
                           mock.Mock(side_effect=[fake_old_network,
                                                  fake_new_network]))
          self.mock_object(self.share_manager, '_update_resource_status')
          self.mock_object(db, 'service_get_by_args',
                           mock.Mock(return_value=fake_service))
          self.mock_object(api.API,
                           'get_share_server_migration_request_spec_dict',
                           mock.Mock(return_value=fake_request_spec))
          self.mock_object(self.share_manager.driver,
                           'share_server_migration_check_compatibility',
                           mock.Mock(return_value=fake_driver_result))
          self.mock_object(self.share_manager,
                           '_validate_check_compatibility_result')
          self.mock_object(self.share_manager,
                           '_provide_share_server_for_migration',
                           mock.Mock(return_value=fake_new_share_server))
          self.mock_object(self.share_manager,
                           '_cast_access_rules_to_readonly_for_server')
          self.mock_object(db, 'share_server_update')
          self.mock_object(self.share_manager.driver,
                           'share_server_migration_start')
  
      @ddt.data(True, False)
      def test__share_server_migration_start_driver(self, writable):
          fake_old_share_server = db_utils.create_share_server()
          fake_new_share_server = db_utils.create_share_server()
          fake_old_network = db_utils.create_share_network()
          fake_new_network = db_utils.create_share_network()
          fake_share_instances = [
              db_utils.create_share(
                  share_server_id=fake_old_share_server['id'],
                  share_network_id=fake_old_network['id'])['instance']]
          fake_share_instance_ids = [
              fake_instance['id'] for fake_instance in fake_share_instances]
          fake_snap_instances = []
          fake_service = {'availability_zone_id': 'fake_az_id',
                          'availability_zone': {'name': 'fake_az1'}}
          fake_request_spec = {}
          fake_dest_host = 'fakehost@fakebackend'
          nondisruptive = False
          preserve_snapshots = True
          fake_driver_result = {
              'compatible': True,
              'writable': writable,
              'preserve_snapshots': preserve_snapshots,
              'nondisruptive': nondisruptive,
              'share_network_id': fake_new_network['id'],
              'migration_cancel': False,
              'migration_get_progress': False
          }
  
          self._setup_server_migration_start_mocks(
              fake_share_instances, fake_snap_instances, fake_old_network,
              fake_new_network, fake_service, fake_request_spec,
              fake_driver_result, fake_new_share_server)
  
          result = self.share_manager._share_server_migration_start_driver(
              self.context, fake_old_share_server, fake_dest_host, writable,
              nondisruptive, preserve_snapshots, fake_new_network['id']
          )
  
          self.assertTrue(result)
          db.share_instances_get_all_by_share_server.assert_called_once_with(
              self.context, fake_old_share_server['id'], with_share_data=True)
          (db.share_snapshot_instance_get_all_with_filters.
              assert_called_once_with(
                  self.context, {'share_instance_ids': fake_share_instance_ids}))
          db.share_network_get.assert_has_calls(
              [mock.call(self.context, fake_old_network['id']),
               mock.call(self.context, fake_new_network['id'])])
          db.service_get_by_args.assert_called_once_with(
              self.context, fake_dest_host, 'manila-share')
          (api.API.get_share_server_migration_request_spec_dict.
              assert_called_once_with(
                  self.context, fake_share_instances, fake_snap_instances,
                  availability_zone_id=fake_service['availability_zone_id'],
                  share_network_id=fake_new_network['id']))
          (self.share_manager.driver.share_server_migration_check_compatibility.
              assert_called_once_with(
                  self.context, fake_old_share_server, fake_dest_host,
                  fake_old_network, fake_new_network, fake_request_spec))
          (self.share_manager._validate_check_compatibility_result.
              assert_called_once_with(
                  self.context, fake_old_share_server, fake_share_instances,
                  fake_snap_instances, fake_driver_result, fake_dest_host,
                  nondisruptive, writable, preserve_snapshots,
                  resource_type='share server'))
          (self.share_manager._provide_share_server_for_migration.
              assert_called_once_with(
                  self.context, fake_old_share_server, fake_new_network['id'],
                  fake_service['availability_zone_id'], fake_dest_host))
          db.share_server_update.assert_has_calls(
              self._get_share_server_start_update_calls(
                  fake_old_share_server, fake_new_share_server))
          (self.share_manager.driver.share_server_migration_start.
              assert_called_once_with(
                  self.context, fake_old_share_server, fake_new_share_server,
                  fake_share_instances, fake_snap_instances))
          if not writable:
              (self.share_manager._cast_access_rules_to_readonly_for_server.
                  assert_called_once_with(
                      self.context, fake_share_instances, fake_old_share_server,
                      dest_host=fake_old_share_server['host']))
          else:
              (self.share_manager._cast_access_rules_to_readonly_for_server.
               assert_not_called())
  
      def test__share_server_migration_start_driver_exception(self):
          fake_old_share_server = db_utils.create_share_server()
          fake_new_share_server = db_utils.create_share_server()
          fake_old_network = db_utils.create_share_network()
          fake_new_network = db_utils.create_share_network()
          fake_share_instances = [
              db_utils.create_share(
                  share_server_id=fake_old_share_server['id'],
                  share_network_id=fake_old_network['id'])['instance']]
          fake_share_instance_ids = [
              fake_instance['id'] for fake_instance in fake_share_instances]
          fake_snap_instances = []
          fake_snap_instance_ids = []
          fake_service = {'availability_zone_id': 'fake_az_id',
                          'availability_zone': {'name': 'fake_az1'}}
          fake_request_spec = {}
          fake_dest_host = 'fakehost@fakebackend'
          nondisruptive = False
          preserve_snapshots = True
          writable = True
          fake_driver_result = {
              'compatible': True,
              'writable': writable,
              'preserve_snapshots': preserve_snapshots,
              'nondisruptive': nondisruptive,
              'share_network_id': fake_new_network['id'],
              'migration_cancel': False,
              'migration_get_progress': False
          }
  
          self._setup_server_migration_start_mocks(
              fake_share_instances, fake_snap_instances, fake_old_network,
              fake_new_network, fake_service, fake_request_spec,
              fake_driver_result, fake_new_share_server)
          mock__reset_read_only = self.mock_object(
              self.share_manager, '_reset_read_only_access_rules_for_server')
  
          self.share_manager.driver.share_server_migration_start.side_effect = (
              Exception
          )
  
          self.assertRaises(
              exception.ShareServerMigrationFailed,
              self.share_manager._share_server_migration_start_driver,
              self.context, fake_old_share_server, fake_dest_host, writable,
              nondisruptive, preserve_snapshots, fake_new_network['id']
          )
  
          db.share_instances_get_all_by_share_server.assert_called_once_with(
              self.context, fake_old_share_server['id'], with_share_data=True)
          (db.share_snapshot_instance_get_all_with_filters.
              assert_called_once_with(
                  self.context, {'share_instance_ids': fake_share_instance_ids}))
          db.share_network_get.assert_has_calls(
              [mock.call(self.context, fake_old_network['id']),
               mock.call(self.context, fake_new_network['id'])])
          self.share_manager._update_resource_status.assert_has_calls([
              mock.call(
                  self.context, constants.STATUS_AVAILABLE,
                  share_instance_ids=fake_share_instance_ids,
                  snapshot_instance_ids=fake_snap_instance_ids)])
          db.service_get_by_args.assert_called_once_with(
              self.context, fake_dest_host, 'manila-share')
          (api.API.get_share_server_migration_request_spec_dict.
              assert_called_once_with(
                  self.context, fake_share_instances, fake_snap_instances,
                  availability_zone_id=fake_service['availability_zone_id'],
                  share_network_id=fake_new_network['id']))
          (self.share_manager.driver.share_server_migration_check_compatibility.
              assert_called_once_with(
                  self.context, fake_old_share_server, fake_dest_host,
                  fake_old_network, fake_new_network, fake_request_spec))
          (self.share_manager._validate_check_compatibility_result.
              assert_called_once_with(
                  self.context, fake_old_share_server, fake_share_instances,
                  fake_snap_instances, fake_driver_result, fake_dest_host,
                  nondisruptive, writable, preserve_snapshots,
                  resource_type='share server'))
          (self.share_manager._provide_share_server_for_migration.
              assert_called_once_with(
                  self.context, fake_old_share_server, fake_new_network['id'],
                  fake_service['availability_zone_id'], fake_dest_host))
          db.share_server_update.assert_has_calls(
              self._get_share_server_start_update_calls(
                  fake_old_share_server, fake_new_share_server,
                  driver_failed=True))
          (self.share_manager.driver.share_server_migration_start.
              assert_called_once_with(
                  self.context, fake_old_share_server, fake_new_share_server,
                  fake_share_instances, fake_snap_instances))
          mock__reset_read_only.assert_called_once_with(
              self.context, fake_share_instances, fake_old_share_server,
              dest_host=fake_old_share_server['host']
          )
  
          if not writable:
              (self.share_manager._cast_access_rules_to_readonly_for_server.
                  assert_called_once_with(
                      self.context, fake_share_instances, fake_old_share_server,
                      fake_old_share_server['host']))
          else:
              (self.share_manager._cast_access_rules_to_readonly_for_server.
               assert_not_called())
  
      @ddt.data(None, exception.ShareServerMigrationFailed)
      def test_share_server_migration_check(self, check_action):
          fake_share_server = db_utils.create_share_server()
          fake_old_network = db_utils.create_share_network()
          fake_new_network = db_utils.create_share_network()
          fake_dest_host = 'fakehost@fakebackend'
          fake_share_instances = [
              db_utils.create_share(
                  share_network_id=fake_old_network['id'])['instance']]
          fake_share_instance_ids = [
              fake_instance['id'] for fake_instance in fake_share_instances]
          fake_snap_instances = []
          fake_service = {'availability_zone_id': 'fake_az_id',
                          'availability_zone': {'name': 'fake_az1'}}
          fake_request_spec = {}
          nondisruptive = False
          writable = True
          preserve_snapshots = True
          fake_driver_result = {
              'compatible': True,
              'writable': writable,
              'preserve_snapshots': preserve_snapshots,
              'nondisruptive': nondisruptive,
              'share_network_id': fake_new_network['id'],
              'migration_cancel': False,
              'migration_get_progress': False
          }
  
          mock_server_get = self.mock_object(
              db, 'share_server_get', mock.Mock(return_value=fake_share_server))
          mock_get_server_instances = self.mock_object(
              db, 'share_instances_get_all_by_share_server',
              mock.Mock(return_value=fake_share_instances))
          mock_snap_instances_get = self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(return_value=fake_snap_instances))
          mock_sn_get = self.mock_object(
              db, 'share_network_get',
              mock.Mock(side_effect=[fake_old_network, fake_new_network]))
          mock_service_get = self.mock_object(
              db, 'service_get_by_args', mock.Mock(return_value=fake_service))
          mock_get_req_spec = self.mock_object(
              api.API, 'get_share_server_migration_request_spec_dict',
              mock.Mock(return_value=fake_request_spec))
          mock_driver_check = self.mock_object(
              self.share_manager.driver,
              'share_server_migration_check_compatibility',
              mock.Mock(return_value=fake_driver_result))
          mock__validate_check_compatibility = self.mock_object(
              self.share_manager, '_validate_check_compatibility_result')
          if isinstance(check_action, exception.ShareServerMigrationFailed):
              mock__validate_check_compatibility.side_effect = (
                  exception.ShareServerMigrationFailed)
              fake_driver_result['compatible'] = False
  
          result = self.share_manager.share_server_migration_check(
              self.context, fake_share_server['id'], fake_dest_host, True, False,
              True, fake_new_network['id']
          )
  
          self.assertEqual(fake_driver_result, result)
          mock_server_get.assert_called_once_with(
              self.context, fake_share_server['id'])
          mock_get_server_instances.assert_called_once_with(
              self.context, fake_share_server['id'], with_share_data=True
          )
          mock_snap_instances_get.assert_called_once_with(
              self.context, {'share_instance_ids': fake_share_instance_ids}
          )
          mock_sn_get.assert_has_calls(
              [mock.call(self.context, fake_old_network['id']),
               mock.call(self.context, fake_new_network['id'])]
          )
          mock_service_get.assert_called_once_with(
              self.context, fake_dest_host, 'manila-share'
          )
          mock_get_req_spec.assert_called_once_with(
              self.context, fake_share_instances, fake_snap_instances,
              availability_zone_id=fake_service['availability_zone_id'],
              share_network_id=fake_new_network['id']
          )
          mock_driver_check.assert_called_once_with(
              self.context, fake_share_server, fake_dest_host, fake_old_network,
              fake_new_network, fake_request_spec
          )
          mock__validate_check_compatibility.assert_called_once_with(
              self.context, fake_share_server, fake_share_instances,
              fake_snap_instances, fake_driver_result, fake_dest_host,
              nondisruptive, writable, preserve_snapshots,
              resource_type='share server'
          )
  
      def test_share_server_migration_check_dhss_false(self):
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = False
          expected = {
              'compatible': False,
              'writable': None,
              'preserve_snapshots': None,
              'nondisruptive': None,
              'share_network_id': 'new_share_network_id',
              'migration_cancel': None,
              'migration_get_progress': None
          }
  
          result = self.share_manager.share_server_migration_check(
              self.context, 'fake_share_server_id', 'fake_dest_host',
              False, False, False, 'new_share_network_id'
          )
  
          self.assertEqual(expected, result)
  
      def test_share_server_migration_start(self):
          fake_share_server = db_utils.create_share_server()
          fake_share_network = db_utils.create_share_server()
          fake_dest_host = 'fakehost@fakebackend'
          writable = True
          nondisruptive = True
          preserve_snapshots = True
  
          mock_server_update = self.mock_object(db, 'share_server_update')
          mock_server_get = self.mock_object(
              db, 'share_server_get', mock.Mock(return_value=fake_share_server))
          mock__server_migration_start_driver = self.mock_object(
              self.share_manager, '_share_server_migration_start_driver')
  
          self.share_manager.share_server_migration_start(
              self.context, fake_share_server['id'], fake_dest_host, writable,
              nondisruptive, preserve_snapshots, fake_share_network['id']
          )
  
          mock_server_update.assert_called_once_with(
              self.context, fake_share_server['id'],
              {'task_state': constants.TASK_STATE_MIGRATION_IN_PROGRESS}
          )
          mock_server_get.assert_called_once_with(
              self.context, fake_share_server['id']
          )
          mock__server_migration_start_driver.assert_called_once_with(
              self.context, fake_share_server, fake_dest_host, writable,
              nondisruptive, preserve_snapshots, fake_share_network['id']
          )
  
      @ddt.data(True, False)
      def test_share_server_migration_start_exception(self, dhss):
          fake_share_server = db_utils.create_share_server()
          fake_share_network = db_utils.create_share_server()
          fake_dest_host = 'fakehost@fakebackend'
          writable = True
          nondisruptive = True
          preserve_snapshots = True
          self.mock_object(self.share_manager, 'driver')
          self.share_manager.driver.driver_handles_share_servers = dhss
  
          mock_server_update = self.mock_object(db, 'share_server_update')
          mock_server_get = self.mock_object(
              db, 'share_server_get', mock.Mock(return_value=fake_share_server))
          mock__server_migration_start_driver = self.mock_object(
              self.share_manager, '_share_server_migration_start_driver',
              mock.Mock(side_effect=exception.ShareServerMigrationFailed))
  
          self.share_manager.share_server_migration_start(
              self.context, fake_share_server['id'], fake_dest_host, writable,
              nondisruptive, preserve_snapshots, fake_share_network['id']
          )
  
          mock_server_update.assert_has_calls([
              mock.call(
                  self.context, fake_share_server['id'],
                  {'task_state': constants.TASK_STATE_MIGRATION_IN_PROGRESS}),
              mock.call(
                  self.context, fake_share_server['id'],
                  {'task_state': constants.TASK_STATE_MIGRATION_ERROR,
                   'status': constants.STATUS_ACTIVE}
              )
          ])
          mock_server_get.assert_called_once_with(
              self.context, fake_share_server['id']
          )
          if dhss:
              mock__server_migration_start_driver.assert_called_once_with(
                  self.context, fake_share_server, fake_dest_host, writable,
                  nondisruptive, preserve_snapshots, fake_share_network['id']
              )
  
      def _setup_migration_continue_mocks(
              self, fake_share_servers, fake_share_instances,
              fake_snapshot_instances):
          self.mock_object(
              db, 'share_server_get_all_by_host',
              mock.Mock(return_value=fake_share_servers))
          self.mock_object(
              db, 'share_instances_get_all_by_share_server',
              mock.Mock(return_value=fake_share_instances))
          self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(return_value=fake_snapshot_instances))
  
      @ddt.data(True, False)
      def test_share_server_migration_continue(self, finished):
          fake_src_share_servers = [
              db_utils.create_share_server(
                  status=constants.STATUS_SERVER_MIGRATING,
                  task_state=constants.TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS)]
          fake_dest_share_servers = [
              db_utils.create_share_server(
                  source_share_server_id=fake_src_share_servers[0]['id'],
                  status=constants.STATUS_SERVER_MIGRATING_TO,
                  task_state=constants.TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS
              )]
          fake_share_instances = [db_utils.create_share()['instance']]
          fake_share_instance_ids = [
              instance['id'] for instance in fake_share_instances]
          fake_cancelled_share_server = db_utils.create_share_server()
          fake_snapshot_instances = []
          server_update_calls = [
              mock.call(
                  self.context, fake_src_share_servers[0]['id'],
                  {
                      'task_state':
                          constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE}),
              mock.call(
                  self.context, fake_dest_share_servers[0]['id'],
                  {
                      'task_state':
                          constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE
                  })
              ]
  
          self._setup_migration_continue_mocks(
              fake_dest_share_servers, fake_share_instances,
              fake_snapshot_instances)
          self.mock_object(db, 'share_server_get',
                           mock.Mock(side_effect=[fake_src_share_servers[0],
                                                  fake_cancelled_share_server]))
          self.mock_object(
              self.share_manager.driver, 'share_server_migration_continue',
              mock.Mock(return_value=finished))
          self.mock_object(db, 'share_server_update')
  
          self.share_manager.share_server_migration_driver_continue(
              self.context)
  
          db.share_server_get_all_by_host.assert_called_once_with(
              self.context, self.share_manager.host,
              filters={'status': constants.STATUS_SERVER_MIGRATING_TO}
          )
          db.share_instances_get_all_by_share_server.assert_called_once_with(
              self.context, fake_src_share_servers[0]['id'],
              with_share_data=True
          )
          (db.share_snapshot_instance_get_all_with_filters.
              assert_called_once_with(
                  self.context, {'share_instance_ids': fake_share_instance_ids}))
          (self.share_manager.driver.share_server_migration_continue.
              assert_called_once_with(
                  self.context, fake_src_share_servers[0],
                  fake_dest_share_servers[0],
                  fake_share_instances, fake_snapshot_instances))
          if finished:
              db.share_server_update.assert_has_calls(server_update_calls)
              db.share_server_get.assert_called_once_with(
                  self.context, fake_src_share_servers[0]['id']
              )
          else:
              db.share_server_get.assert_has_calls([
                  mock.call(self.context, fake_src_share_servers[0]['id']),
                  mock.call(self.context, fake_src_share_servers[0]['id']),
              ])
  
      @ddt.data(
          {
              'src_share_server_exists': False,
              'action_migration_continue': {
                  'return_value': True
              }
          },
          {
              'src_share_server_exists': True,
              'action_migration_continue': {
                  'side_effect': Exception
              }
          }
      )
      @ddt.unpack
      def test_share_server_migration_continue_exception(
              self, src_share_server_exists, action_migration_continue):
          fake_src_share_server = db_utils.create_share_server(
              status=constants.STATUS_SERVER_MIGRATING,
              task_state=constants.TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS)
          fake_dest_share_servers = [
              db_utils.create_share_server(
                  source_share_server_id=fake_src_share_server['id'],
                  status=constants.STATUS_SERVER_MIGRATING_TO,
                  task_state=constants.TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS)]
          fake_share_instances = [db_utils.create_share()['instance']]
          fake_share_instance_ids = [
              instance['id'] for instance in fake_share_instances]
          fake_snapshot_instances = []
          fake_snapshot_instance_ids = []
  
          server_update_calls = [mock.call(
              self.context, fake_dest_share_servers[0]['id'],
              {'task_state': constants.TASK_STATE_MIGRATION_ERROR,
               'status': constants.STATUS_ERROR}
          )]
          if src_share_server_exists:
              self.mock_object(db, 'share_server_get',
                               mock.Mock(return_value=fake_src_share_server))
              server_update_calls.append(
                  mock.call(
                      self.context, fake_src_share_server['id'],
                      {
                          'task_state': constants.TASK_STATE_MIGRATION_ERROR,
                          'status': constants.STATUS_ACTIVE
                      }))
          else:
              self.mock_object(db, 'share_server_get',
                               mock.Mock(return_value=None))
  
          self._setup_migration_continue_mocks(
              fake_dest_share_servers, fake_share_instances,
              fake_snapshot_instances)
          mock_server_update = self.mock_object(db, 'share_server_update')
          self.mock_object(
              self.share_manager.driver, 'share_server_migration_continue',
              mock.Mock(**action_migration_continue)
          )
          mock__update_resource_status = self.mock_object(
              self.share_manager, '_update_resource_status')
          mock__rest_read_only_access_rules = self.mock_object(
              self.share_manager, '_reset_read_only_access_rules_for_server'
          )
  
          self.share_manager.share_server_migration_driver_continue(
              self.context)
  
          db.share_server_get_all_by_host.assert_called_once_with(
              self.context, self.share_manager.host,
              filters={'status': constants.STATUS_SERVER_MIGRATING_TO})
          db.share_server_get.assert_called_once_with(
              self.context, fake_src_share_server['id'])
          if src_share_server_exists:
              db.share_instances_get_all_by_share_server.assert_called_once_with(
                  self.context, fake_src_share_server['id'],
                  with_share_data=True)
              (db.share_snapshot_instance_get_all_with_filters.
                  assert_called_once_with(
                      self.context,
                      {'share_instance_ids': fake_share_instance_ids}))
              mock__update_resource_status.assert_called_once_with(
                  self.context, constants.STATUS_AVAILABLE,
                  share_instance_ids=fake_share_instance_ids,
                  snapshot_instance_ids=fake_snapshot_instance_ids
              )
              mock__rest_read_only_access_rules.assert_called_once_with(
                  self.context, fake_share_instances, fake_src_share_server,
                  dest_host=fake_src_share_server['host']
              )
              mock_server_update.assert_has_calls(server_update_calls)
  
      def _setup_server_migration_complete_mocks(
              self, fake_source_share_server, fake_dest_share_server,
              fake_share_instances, fake_snapshot_instances):
          self.mock_object(
              db, 'share_server_get',
              mock.Mock(side_effect=[fake_dest_share_server,
                                     fake_source_share_server]))
          self.mock_object(
              db, 'share_instances_get_all_by_share_server',
              mock.Mock(return_value=fake_share_instances))
          self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(return_value=fake_snapshot_instances))
          self.mock_object(
              self.share_manager, '_update_resource_status')
          self.mock_object(db, 'share_server_update')
  
      def test_share_server_migration_complete_exception(self):
          fake_source_share_server = db_utils.create_share_server()
          fake_dest_share_server = db_utils.create_share_server()
          fake_share_instances = [db_utils.create_share()['instance']]
          fake_share_instance_ids = [
              instance['id'] for instance in fake_share_instances]
          fake_snapshot_instances = []
          fake_snapshot_instance_ids = []
  
          self._setup_server_migration_complete_mocks(
              fake_source_share_server, fake_dest_share_server,
              fake_share_instances, fake_snapshot_instances
          )
          mock__server_migration_complete = self.mock_object(
              self.share_manager, '_server_migration_complete_driver',
              mock.Mock(side_effect=Exception))
  
          self.assertRaises(
              exception.ShareServerMigrationFailed,
              self.share_manager.share_server_migration_complete,
              self.context, fake_source_share_server['id'],
              fake_dest_share_server['id']
          )
          db.share_server_get.assert_has_calls(
              [mock.call(self.context, fake_dest_share_server['id']),
               mock.call(self.context, fake_source_share_server['id'])]
          )
          db.share_instances_get_all_by_share_server.assert_called_once_with(
              self.context, fake_source_share_server['id'], with_share_data=True)
          (db.share_snapshot_instance_get_all_with_filters.
              assert_called_once_with(
                  self.context, {'share_instance_ids': fake_share_instance_ids}))
          mock__server_migration_complete.assert_called_once_with(
              self.context, fake_source_share_server, fake_share_instances,
              fake_snapshot_instances, fake_dest_share_server)
          self.share_manager._update_resource_status.assert_called_once_with(
              self.context, constants.STATUS_ERROR,
              share_instance_ids=fake_share_instance_ids,
              snapshot_instance_ids=fake_snapshot_instance_ids)
          db.share_server_update.assert_has_calls([
              mock.call(self.context, fake_source_share_server['id'],
                        {'task_state': constants.TASK_STATE_MIGRATION_ERROR,
                         'status': constants.STATUS_ERROR}),
              mock.call(
                  self.context, fake_dest_share_server['id'],
                  {'task_state': constants.TASK_STATE_MIGRATION_ERROR,
                   'status': constants.STATUS_ERROR})])
  
      def test_share_server_migration_complete(self):
          fake_source_share_server = db_utils.create_share_server()
          fake_dest_share_server = db_utils.create_share_server()
          fake_share_instances = [db_utils.create_share()['instance']]
          fake_share_instance_ids = [
              instance['id'] for instance in fake_share_instances]
          fake_snapshot_instances = []
          fake_snapshot_instance_ids = []
  
          self._setup_server_migration_complete_mocks(
              fake_source_share_server, fake_dest_share_server,
              fake_share_instances, fake_snapshot_instances
          )
          mock__server_migration_complete = self.mock_object(
              self.share_manager, '_server_migration_complete_driver')
  
          self.share_manager.share_server_migration_complete(
              self.context, fake_source_share_server['id'],
              fake_dest_share_server['id'])
          db.share_server_get.assert_has_calls(
              [mock.call(self.context, fake_dest_share_server['id']),
               mock.call(self.context, fake_source_share_server['id'])]
          )
          db.share_instances_get_all_by_share_server.assert_called_once_with(
              self.context, fake_source_share_server['id'], with_share_data=True)
          (db.share_snapshot_instance_get_all_with_filters.
              assert_called_once_with(
                  self.context, {'share_instance_ids': fake_share_instance_ids}))
          mock__server_migration_complete.assert_called_once_with(
              self.context, fake_source_share_server, fake_share_instances,
              fake_snapshot_instances, fake_dest_share_server)
          self.share_manager._update_resource_status.assert_called_once_with(
              self.context, constants.STATUS_AVAILABLE,
              share_instance_ids=fake_share_instance_ids,
              snapshot_instance_ids=fake_snapshot_instance_ids)
          db.share_server_update.assert_called_once_with(
              self.context, fake_dest_share_server['id'],
              {'task_state': constants.TASK_STATE_MIGRATION_SUCCESS,
               'status': constants.STATUS_ACTIVE})
  
      @ddt.data(
          {'unmanage_source_server': False,
           'snapshot_updates': {},
           'share_updates': {}},
          {'unmanage_source_server': True,
           'snapshot_updates': {},
           'share_updates': {}},
      )
      def test__server_migration_complete_driver(self, model_update):
          fake_share_network = db_utils.create_share_network()
          fake_share_network_subnet = db_utils.create_share_network_subnet(
              share_network_id=fake_share_network['id'])
          fake_source_share_server = db_utils.create_share_server()
          fake_dest_share_server = db_utils.create_share_server(
              share_network_subnet_id=fake_share_network_subnet['id'])
          fake_share = db_utils.create_share()
          fake_snapshot = db_utils.create_snapshot(share_id=fake_share['id'])
          fake_service = {'availability_zone_id': 'fake_az_id',
                          'availability_zone': {'name': 'fake_az1'}}
          fake_share_instances = [fake_share['instance']]
          fake_snapshot_instances = [fake_snapshot['instance']]
          fake_share_instance_id = fake_share['instance']['id']
          fake_allocation_data = {}
          model_update['share_updates'][fake_share['instance']['id']] = {
              'export_locations': {
                  "path": "10.10.10.31:/fake_mount_point",
                  "metadata": {
                      "preferred": True,
                  },
                  "is_admin_only": False,
              },
              'pool_name': 'fakepool'
          }
          snapshot_el_update = {
              "path": "10.10.10.31:/fake_snap_mount_point",
              "is_admin_only": False,
          }
          model_update['snapshot_updates'][fake_snapshot['instance']['id']] = {
              'export_locations': [snapshot_el_update]
          }
          fake_instance_update = {
              'share_server_id': fake_dest_share_server['id'],
              'host': fake_dest_share_server['host'] + '#fakepool',
              'share_network_id': fake_share_network['id'],
              'availability_zone_id': fake_service['availability_zone_id'],
          }
  
          mock_server_update = self.mock_object(db, 'share_server_update')
          mock_network_get = self.mock_object(
              db, 'share_network_get', mock.Mock(return_vale=fake_share_network))
          mock_subnet_get = self.mock_object(
              db, 'share_network_subnet_get',
              mock.Mock(return_value=fake_share_network_subnet))
          self.mock_object(
              self.share_manager, '_form_server_setup_info',
              mock.Mock(return_value=fake_allocation_data))
          mock_server_migration_complete = self.mock_object(
              self.share_manager.driver, 'share_server_migration_complete',
              mock.Mock(return_value=model_update))
          mock_service_get_by_args = self.mock_object(
              db, 'service_get_by_args', mock.Mock(return_value=fake_service))
          mock_instance_update = self.mock_object(db, 'share_instance_update')
          mock_el_update = self.mock_object(db, 'share_export_locations_update')
          mock_snap_el_update = self.mock_object(
              db, 'share_snapshot_instance_export_locations_update')
          mock_reset_access_rules = self.mock_object(
              self.share_manager, '_reset_read_only_access_rules_for_server')
          mock_unmanage_server = self.mock_object(
              rpcapi.ShareAPI, 'unmanage_share_server')
          mock_check_delete_server = self.mock_object(
              self.share_manager, '_check_delete_share_server')
  
          self.share_manager._server_migration_complete_driver(
              self.context, fake_source_share_server, fake_share_instances,
              fake_snapshot_instances, fake_dest_share_server)
  
          mock_server_update.assert_has_calls(
              [mock.call(
                  self.context, fake_source_share_server['id'],
                  {'task_state': constants.TASK_STATE_MIGRATION_COMPLETING}),
               mock.call(
                   self.context, fake_dest_share_server['id'],
                   {'task_state': constants.TASK_STATE_MIGRATION_COMPLETING}),
               mock.call(
                   self.context, fake_source_share_server['id'],
                   {'task_state': constants.TASK_STATE_MIGRATION_SUCCESS,
                    'status': constants.STATUS_INACTIVE})])
          mock_network_get.assert_called_once_with(
              self.context, fake_share_network['id'])
          mock_subnet_get.assert_called_once_with(
              self.context, fake_share_network_subnet['id'])
          mock_server_migration_complete.assert_called_once_with(
              self.context, fake_source_share_server, fake_dest_share_server,
              fake_share_instances, fake_snapshot_instances, fake_allocation_data
          )
          mock_service_get_by_args.assert_called_once_with(
              self.context, fake_dest_share_server['host'], 'manila-share')
          mock_instance_update.assert_called_once_with(
              self.context, fake_share_instance_id, fake_instance_update)
          mock_el_update.assert_called_once_with(
              self.context, fake_share_instance_id,
              model_update['share_updates'][fake_share_instance_id][
                  'export_locations'])
          mock_snap_el_update.assert_called_once_with(
              self.context, fake_snapshot['instance']['id'], [snapshot_el_update]
          )
          mock_reset_access_rules.assert_called_once_with(
              self.context, fake_share_instances, fake_source_share_server,
              dest_host=fake_source_share_server['host'])
          if model_update.get('unmanage_share_server') is True:
              mock_unmanage_server.assert_called_once_with(
                  self.context, fake_source_share_server)
          else:
              mock_check_delete_server.assert_called_once_with(
                  self.context, share_server=fake_source_share_server,
                  remote_host=True
              )
  
      @ddt.data(constants.TASK_STATE_MIGRATION_SUCCESS,
                constants.TASK_STATE_MIGRATION_IN_PROGRESS)
      def test_server_migration_cancel_exception(self, task_state):
          fake_source_share_server = db_utils.create_share_server(
              task_state=task_state)
          fake_dest_share_server = db_utils.create_share_server()
  
          mock_server_get = self.mock_object(
              db, 'share_server_get',
              mock.Mock(side_effect=[fake_source_share_server,
                                     fake_dest_share_server]))
  
          self.assertRaises(
              exception.InvalidShareServer,
              self.share_manager.share_server_migration_cancel,
              self.context, fake_source_share_server['id'],
              fake_dest_share_server['id']
          )
  
          mock_server_get.assert_has_calls([
              mock.call(self.context, fake_source_share_server['id']),
              mock.call(self.context, fake_dest_share_server['id'])])
  
      @ddt.data(
          constants.TASK_STATE_MIGRATION_DRIVER_PHASE1_DONE,
          constants.TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS)
      def test_share_server_migration_cancel(self, task_state):
          fake_source_share_server = db_utils.create_share_server(
              task_state=task_state)
          fake_dest_share_server = db_utils.create_share_server()
          fake_share = db_utils.create_share()
          fake_share_instances = [fake_share['instance']]
          fake_share_instance_ids = [fake_share['instance']['id']]
          fake_snapshot = db_utils.create_snapshot(share_id=fake_share['id'])
          fake_snapshot_instances = [fake_snapshot['instance']]
          fake_snapshot_instance_ids = [fake_snapshot['instance']['id']]
  
          mock_server_get = self.mock_object(
              db, 'share_server_get',
              mock.Mock(side_effect=[fake_source_share_server,
                                     fake_dest_share_server]))
          mock_get_instances = self.mock_object(
              db, 'share_instances_get_all_by_share_server',
              mock.Mock(return_value=fake_share_instances))
          mock_get_snap_instances = self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(return_value=fake_snapshot_instances))
          mock_migration_cancel = self.mock_object(
              self.share_manager.driver, 'share_server_migration_cancel')
          mock_server_update = self.mock_object(db, 'share_server_update')
          mock_check_delete_server = self.mock_object(
              self.share_manager, '_check_delete_share_server')
          mock_update_resource = self.mock_object(
              self.share_manager, '_update_resource_status')
          mock_reset_read_only_rules = self.mock_object(
              self.share_manager, '_reset_read_only_access_rules_for_server')
  
          self.share_manager.share_server_migration_cancel(
              self.context, fake_source_share_server['id'],
              fake_dest_share_server['id'])
  
          mock_server_get.assert_has_calls([
              mock.call(self.context, fake_source_share_server['id']),
              mock.call(self.context, fake_dest_share_server['id'])])
          mock_get_instances.assert_called_once_with(
              self.context, fake_source_share_server['id'], with_share_data=True)
          mock_get_snap_instances.assert_called_once_with(
              self.context, {'share_instance_ids': fake_share_instance_ids})
          mock_migration_cancel.assert_called_once_with(
              self.context, fake_source_share_server, fake_dest_share_server,
              fake_share_instances, fake_snapshot_instances)
          mock_server_update.assert_has_calls([
              mock.call(
                  self.context, fake_dest_share_server['id'],
                  {'task_state': constants.TASK_STATE_MIGRATION_CANCELLED,
                   'status': constants.STATUS_INACTIVE}
              ),
              mock.call(
                  self.context, fake_source_share_server['id'],
                  {'task_state': constants.TASK_STATE_MIGRATION_CANCELLED,
                   'status': constants.STATUS_ACTIVE}
              )
          ])
          mock_check_delete_server.assert_called_once_with(
              self.context, share_server=fake_dest_share_server)
          mock_update_resource.assert_called_once_with(
              self.context, constants.STATUS_AVAILABLE,
              share_instance_ids=fake_share_instance_ids,
              snapshot_instance_ids=fake_snapshot_instance_ids)
          mock_reset_read_only_rules.assert_called_once_with(
              self.context, fake_share_instances, fake_source_share_server,
              dest_host=fake_source_share_server['host'])
  
      @ddt.data(
          constants.TASK_STATE_MIGRATION_STARTING,
          constants.TASK_STATE_MIGRATION_CANCELLED,
      )
      def test_migration_get_progress_exception(self, task_state):
          fake_source_share_server = db_utils.create_share_server(
              task_state=task_state)
          fake_dest_share_server = db_utils.create_share_server()
  
          self.mock_object(
              db, 'share_server_get',
              mock.Mock(side_effect=[fake_source_share_server,
                                     fake_dest_share_server]))
  
          self.assertRaises(
              exception.InvalidShareServer,
              self.share_manager.share_server_migration_cancel,
              self.context, fake_source_share_server['id'],
              fake_dest_share_server['id']
          )
  
      def test_share_server_migration_get_progress(self):
          fake_source_share_server = db_utils.create_share_server(
              task_state=constants.TASK_STATE_MIGRATION_DRIVER_IN_PROGRESS)
          fake_dest_share_server = db_utils.create_share_server()
          fake_progress = {"total_progress": 75}
          fake_share = db_utils.create_share()
          fake_share_instances = [fake_share['instance']]
          fake_share_instance_ids = [fake_share['instance']['id']]
          fake_snapshot = db_utils.create_snapshot(share_id=fake_share['id'])
          fake_snapshot_instances = [fake_snapshot['instance']]
  
          mock_server_get = self.mock_object(
              db, 'share_server_get',
              mock.Mock(side_effect=[fake_source_share_server,
                                     fake_dest_share_server]))
          mock_get_instances = self.mock_object(
              db, 'share_instances_get_all_by_share_server',
              mock.Mock(return_value=fake_share_instances))
          mock_get_snap_instances = self.mock_object(
              db, 'share_snapshot_instance_get_all_with_filters',
              mock.Mock(return_value=fake_snapshot_instances))
          mock_migration_get_progress = self.mock_object(
              self.share_manager.driver, 'share_server_migration_get_progress',
              mock.Mock(return_value=fake_progress))
  
          self.share_manager.share_server_migration_get_progress(
              self.context, fake_source_share_server['id'],
              fake_dest_share_server['id'])
  
          mock_get_instances.assert_called_once_with(
              self.context, fake_source_share_server['id'], with_share_data=True)
          mock_get_snap_instances.assert_called_once_with(
              self.context, {'share_instance_ids': fake_share_instance_ids})
          mock_server_get.assert_has_calls([
              mock.call(self.context, fake_source_share_server['id']),
              mock.call(self.context, fake_dest_share_server['id'])])
          mock_migration_get_progress.assert_called_once_with(
              self.context, fake_source_share_server, fake_dest_share_server,
              fake_share_instances, fake_snapshot_instances)
  
  
  @ddt.ddt
  class HookWrapperTestCase(test.TestCase):
  
      def setUp(self):
          super(HookWrapperTestCase, self).setUp()
          self.configuration = mock.Mock()
          self.configuration.safe_get.return_value = True
  
      @manager.add_hooks
      def _fake_wrapped_method(self, some_arg, some_kwarg):
          return "foo"
  
      def test_hooks_enabled(self):
          self.hooks = [mock.Mock(return_value=i) for i in range(2)]
  
          result = self._fake_wrapped_method(
              "some_arg", some_kwarg="some_kwarg_value")
  
          self.assertEqual("foo", result)
          for i, mock_hook in enumerate(self.hooks):
              mock_hook.execute_pre_hook.assert_called_once_with(
                  "some_arg",
                  func_name="_fake_wrapped_method",
                  some_kwarg="some_kwarg_value")
              mock_hook.execute_post_hook.assert_called_once_with(
                  "some_arg",
                  func_name="_fake_wrapped_method",
                  driver_action_results="foo",
                  pre_hook_data=self.hooks[i].execute_pre_hook.return_value,
                  some_kwarg="some_kwarg_value")
  
      def test_hooks_disabled(self):
          self.hooks = []
  
          result = self._fake_wrapped_method(
              "some_arg", some_kwarg="some_kwarg_value")
  
          self.assertEqual("foo", result)
          for mock_hook in self.hooks:
              self.assertFalse(mock_hook.execute_pre_hook.called)
              self.assertFalse(mock_hook.execute_post_hook.called)
  